ForeignKey(User,unique = True)和OneToOneField之间的区别

时间:2012-03-30 19:09:11

标签: django django-models

Django中models.ForeignKey(Modelname, unique=True)models.OneToOneField之间的区别是什么?

我应该在哪里使用models.OneToOneFieldmodels.ForeignKey(Modelname, unique=True)

2 个答案:

答案 0 :(得分:44)

OneToOneFieldForeignKeyunique=True非常相似。除非你正在进行多表继承,在这种情况下你必须使用OneToOneField,唯一真正的区别是用于访问相关对象的api。

Django docs中说:

  

从概念上讲,这类似于ForeignKey unique=True,但关系的“反向”将直接返回单个对象。

让我们用一个例子说明这意味着什么。考虑两个模型,PersonAddress。我们假设每个人都有一个独特的地址。

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。 我希望这有助于说明所创建的关系之间的差异。