7

I need to extend django user with some additional fields . I found 2 different ways there

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    #other fields

OR

class UserProfile(models.Model):
    user = models.ForeignKey(User)
    #other fields

Aren't they same? After syncing them, i saw no difference in mysql database

Dan Hanly
  • 7,829
  • 13
  • 73
  • 134
sumit
  • 15,003
  • 12
  • 69
  • 110

2 Answers2

6

No, why would you think that? A ForeignKey is a one-to-many relationship - ie a user could have many profiles. A OneToOne is, as the name implies, a one-to-one relationship - a user can only have one profile, which sounds more likely.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • After syncing them, i saw no difference in mysql database, i was asking how it distinguish – sumit May 17 '12 at 15:08
  • 10
    The only difference *in the database* is a unique constraint on the column with a one-to-one. In fact, `OneToOneField` is merely just `ForeignKey(unique=True)`. – Chris Pratt May 17 '12 at 15:12
  • 1
    You wouldn't see any difference in your database, as syncdb does not change tables once they are defined, you would need to drop and recreate them. However you can use `sqlall` to show the different outputs - as Chris says, a OneToOne has a unique constraint. – Daniel Roseman May 17 '12 at 15:16
4

As @Daniel Roseman said, these are 2 different types of rdbms relationships.

You will find that it distinguishes in the situation where you will have(by mistake probably) more than one profiles for a given user. In that situation myuser.get_profile() will raise a MultipleObjectsReturned exception, since essentially it is doing a get() query, under the hood.

rantanplan
  • 7,283
  • 1
  • 24
  • 45
  • +1 Good point. You could technically use a ForeignKey, but setting it up as a proper one-to-one protects you from yourself by raising an exception if you attempt to create more than one profile. – Chris Pratt May 17 '12 at 15:28
  • @ChrisPratt Yes. Basically if you do it with a ForeignKey you deviate so much from the django spec(since you render get_profile useless), that you're better off by naming your extension model something other than `UserProfile`. – rantanplan May 17 '12 at 15:32