Что отличается между 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
. Надеюсь, это поможет проиллюстрировать различия между созданными отношениями.