Что отличается между models.ForeignKey(Modelname, unique=True) и models.OneToOneField в Django?
Где я должен использовать models.OneToOneField и models.ForeignKey(Modelname, unique=True)?
Что отличается между models.ForeignKey(Modelname, unique=True) и models.OneToOneField в Django?
Где я должен использовать models.OneToOneField и models.ForeignKey(Modelname, unique=True)?
OneToOneField очень похож на ForeignKey с unique=True. Если вы не используете множественное наследование таблиц, в этом случае вам нужно использовать OneToOneField, единственное реальное различие - это api для доступа к связанным объектам.
В документах Django говорится:
Концептуально это похоже на
ForeignKeyсunique=True, но "обратная" сторона отношения будет напрямую возвращать один объект.
Покажем, что это значит с примером. Рассмотрим две модели: " Person и 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)
Если вы начинаете с человека, вы можете легко получить доступ к адресу:
address = person.address
Однако, если вы начинаете с адреса, вам нужно пройти через диспетчер person_set чтобы получить человека.
person = address.person_set.get() # may raise Person.DoesNotExist
Теперь замените ForeignKey на 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)
Если вы начинаете с человека, вы можете получить доступ к адресу таким же образом:
address = person.address
И теперь мы можем легко получить доступ к человеку из адреса.
person = address.person # may raise Person.DoesNotExist
Когда вы получаете доступ к OneToOneField вы получаете значение поля, которое вы запрашивали. В этом примере поле "title" в книжной модели - OneToOneField:
>>> from mysite.books.models import Book
>>> b = Book.objects.get(id=50)
>>> b.title
u'The Django Book'
Когда вы ForeignKey к ForeignKey вы получаете связанный с ним объект модели, который затем можно запрограммировать на дальнейшие запросы. В этом примере одно и то же поле книги "издатель" - это ForeignKey (соотносится с определением модели класса Publisher):
>>> b = Book.objects.get(id=50)
>>> b.publisher
<Publisher: Apress Publishing>
>>> b.publisher.website
u'http://www.apress.com/'
С ForeignKey полей ForeignKey работают и наоборот, но они немного отличаются из-за несимметричного характера отношений.
>>> p = Publisher.objects.get(name='Apress Publishing')
>>> p.book_set.all()
[<Book: The Django Book>, <Book: Dive Into Python>, ...]
За кулисами book_set - это всего лишь QuerySet и его можно фильтровать и нарезать, как и любой другой QuerySet. Имя book_set атрибута создается путем добавления имени модели нижнего регистра в _set. Надеюсь, это поможет проиллюстрировать различия между созданными отношениями.