What is different between models.ForeignKey(Modelname, unique=True) and models.OneToOneField in Django?
Where should I use models.OneToOneField and models.ForeignKey(Modelname, unique=True)?
What is different between models.ForeignKey(Modelname, unique=True) and models.OneToOneField in Django?
Where should I use models.OneToOneField and models.ForeignKey(Modelname, unique=True)?
A OneToOneField is very similar to a ForeignKey with unique=True. Unless you are doing multiple table inheritance, in which case you have to use OneToOneField, the only real difference is the api for accessing related objects.
In the Django docs it says:
Conceptually, this is similar to a
ForeignKeywithunique=True, but the "reverse" side of the relation will directly return a single object.
Let's show what that means with an example. Consider two models, Person and Address. We'll assume each person has a unique address.
class Person(models.Model):
name = models.CharField(max_length=50)
address = models.ForeignKey('Address', unique=True)
class Address(models.Model):
street = models.CharField(max_length=50)
If you start with a person, you can access the address easily:
address = person.address
However if you start with an address, you have to go via the person_set manager to get the person.
person = address.person_set.get() # may raise Person.DoesNotExist
Now let's replace the ForeignKey with a OneToOneField.
class Person(models.Model):
name = models.CharField(max_length=50)
address = models.OneToOneField('Address')
class Address(models.Model):
street = models.CharField(max_length=50)
If you start with a person, you can access the address in the same way:
address = person.address
And now, we can access the person from the address more easily.
person = address.person # may raise Person.DoesNotExist
When you access a OneToOneField you get the value of the field you queried. In this example a book model's 'title' field is a OneToOneField:
>>> from mysite.books.models import Book
>>> b = Book.objects.get(id=50)
>>> b.title
u'The Django Book'
When you access a ForeignKey you get the related model object, which you can then preform further queries against. In this example the same book model's 'publisher' field is a ForeignKey (correlating to the Publisher class model definition):
>>> b = Book.objects.get(id=50)
>>> b.publisher
<Publisher: Apress Publishing>
>>> b.publisher.website
u'http://www.apress.com/'
With ForeignKey fields queries work the other way too, but they're slightly different due to the non-symmetrical nature of the relationship.
>>> p = Publisher.objects.get(name='Apress Publishing')
>>> p.book_set.all()
[<Book: The Django Book>, <Book: Dive Into Python>, ...]
Behind the scenes, book_set is just a QuerySet and can be filtered and sliced like any other QuerySet. The attribute name book_set is generated by appending the lower case model name to _set.
I hope this helps illustrate the differences between the relationships created.