Django中models.ForeignKey(Modelname, unique=True)
和models.OneToOneField
之间的区别是什么?
我应该在哪里使用models.OneToOneField
和models.ForeignKey(Modelname, unique=True)
?
答案 0 :(得分:44)
OneToOneField
与ForeignKey
与unique=True
非常相似。除非你正在进行多表继承,在这种情况下你必须使用OneToOneField
,唯一真正的区别是用于访问相关对象的api。
在Django docs中说:
从概念上讲,这类似于
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
答案 1 :(得分:1)
当您访问OneToOneField
时,您将获得所查询字段的值。在此示例中,图书模型的“标题”字段为OneToOneField
:
>>> from mysite.books.models import Book
>>> b = Book.objects.get(id=50)
>>> b.title
u'The Django Book'
当您访问ForeignKey
时,您将获得相关的模型对象,然后您可以对其进行进一步的查询。在此示例中,相同图书模型的“发布商”字段为ForeignKey
(与Publisher
类模型定义相关):
>>> b = Book.objects.get(id=50)
>>> b.publisher
<Publisher: Apress Publishing>
>>> b.publisher.website
u'http://www.apress.com/'
对于ForeignKey
字段,查询也会以相反的方式工作,但由于关系的非对称性,它们会略有不同。
>>> p = Publisher.objects.get(name='Apress Publishing')
>>> p.book_set.all()
[<Book: The Django Book>, <Book: Dive Into Python>, ...]
在幕后,book_set只是QuerySet
,可以像其他任何QuerySet
一样进行过滤和切片。通过将小写模型名称附加到_set
来生成属性名称book_set。
我希望这有助于说明所创建的关系之间的差异。