1

I'm creating a simple weight management application where users can register, login and update information such as weight, body measurements etc. I've not used Django for a little while and slowly learning best practices from where i left off a little while ago.

I'm using the django-allauth to manage the user registration as this allows people to login with Facebook etc.

I've created a simple app called 'Stats' with a ForignKey to the Users.

class Stat(models.Model):

    user = models.ForeignKey(User, default=False)

    height = models.CharField(max_length=20)
    weight = models.CharField(max_length=20)

    waist = models.CharField(max_length=20)
    hips = models.CharField(max_length=20)
    upperleg = models.CharField(max_length=20)

    upperleg = models.CharField(max_length=20)
    calf = models.CharField(max_length=20)

    bodyfat = models.CharField(max_length=20)

What i would like the user to be able to do is login and update stats on a daily / weekly basis. Then to be able review previous stats. This will probably be done via a model form based on the above approach. I will add more complexity as time goes on.

Is there another way to do that would have any advantages? If the best approach is the best? Is there a way i can list all the objects from that model inside the users page in the admin to be able to reviews users stats easily enough?

Thanks in advance.

JDavies
  • 2,730
  • 7
  • 34
  • 54

1 Answers1

2

It is recommended that you create a separate user profile model for app-specific functionality that relates to a User of your app. It's best to create a UserProfile model which has a OneToOneField link to User object. Then, your Stat model can ForeignKey to UserProfile instead of User. This is to provide abstraction to the User object and give flexibility if you decide to create another Django app in the same project that requires different specifications for the user. Also, with UserProfile you can add customised fields that are app specific.

Another thing you can do to improve this modelling is create separate entities for each stat. For example, HeightWeightStat, WaistStat. But, this is not completely necessary and totally depends on your preference.

To display all of the user related Stat instances in the admin page, use Django Admin inlines: https://docs.djangoproject.com/en/1.10/ref/contrib/admin/#inlinemodeladmin-objects

zubhav
  • 1,519
  • 1
  • 13
  • 19
  • Hi @zubhav thanks for your reply, that's helped out a lot. Just so i'm clear would you extend the user model inside each app that needs access to the Users? So inside my 'stats' app create a new UserProfile model? Or create a new app for the UserProfile? I'm sure it's the first one, but i just want to make sure that's correct. I've found a nice little write up here - https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html#onetoone – JDavies Dec 12 '16 at 08:39
  • 1
    Instead of 'extending' the User model, you should create a whole different model which has a OneToOne link to User. This is just because User is a model which should be strictly used to identify/authenticate someone. It's not really best to have extra fields in the User object like height and weight, simply because it doesn't relate to the entity directly. Maybe ^ the above is actually what you meant, but you said 'extend' so I just wanted to clarify. But yes, inside every new app, you would create a new profile model. – zubhav Dec 12 '16 at 08:53
  • 1
    I just clicked the link you attached. Yes, that is the correct way! – zubhav Dec 12 '16 at 08:55
  • Brilliant thanks you! I think i was getting confused by 'extending' the user model. Ok, so i've now created a Profile model inside my app that has a OneToOneField to the User model. I can see now how that would work in terms of updating the user profile without effecting the User object. Thanks again! – JDavies Dec 12 '16 at 08:56
  • I've just noticed the OneToOne field won't work for me as the stats will need to be added weekly and i can only have one object using that field. So i've reverted back to using a ForeignKey which seems to be working at the moment. However, I will be using a OneToOne for generic profile information, such as bio, images etc :) – JDavies Dec 12 '16 at 14:53
  • 1
    The purpose of the OneToOneField was to link User to UserProfile. The storing of stats should be a completely separate model. Something like this: class Stat(models.Model): user_profile = models.ForeignKey(UserProfile) height = models.CharField() ... – zubhav Dec 12 '16 at 15:13
  • Yep i'm with you. Apologies for the misunderstanding. So the UserProfile model should have the additional fields, then the Stats model should have a ForeignKey to the newly created UserProfile. – JDavies Dec 12 '16 at 15:40