Django 中的 OneToOneField() 与foreignkey()
Django OneToOneField
和 ForeignKey
之间有什么区别?
What's the difference between Django OneToOneField
and ForeignKey
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
OneToOneField(SomeModel)
和ForeignKey(SomeModel, unique=True)
之间的差异,如 Django 权威指南:与
OneToOneField
“反向”关系相反,ForeignKey
“反向”关系返回一个QuerySet
。示例
例如,如果我们有以下两个模型(完整模型代码如下):
Car
模型使用OneToOneField(Engine)
Car2
模型使用 < code>ForeignKey(Engine2, unique=True)从
python manage.py shell
执行以下命令:OneToOneField
示例ForeignKey
为unique=True
示例模型代码
Differences between
OneToOneField(SomeModel)
andForeignKey(SomeModel, unique=True)
as stated in The Definitive Guide to Django:In contrast to the
OneToOneField
"reverse" relation, aForeignKey
"reverse" relation returns aQuerySet
.Example
For example, if we have the following two models (full model code below):
Car
model usesOneToOneField(Engine)
Car2
model usesForeignKey(Engine2, unique=True)
From within
python manage.py shell
execute the following:OneToOneField
ExampleForeignKey
withunique=True
ExampleModel Code
ForeignKey
是多对一关系。因此,Car
对象可能有许多Wheel
实例。因此,每个Wheel
都会有一个指向其所属Car
的ForeignKey
。OneToOneField
就像Engine
的一个实例,其中Car
对象有至多一个且仅有一个。A
ForeignKey
is a many-to-one relationship. So, aCar
object might have many instances ofWheel
. EachWheel
would consequently have aForeignKey
to theCar
it belongs to. AOneToOneField
would be like an instance ofEngine
, where aCar
object has at most one and only one.学习新事物最好、最有效的方法是查看和研究现实世界的实际例子。假设您想在 django 中构建一个博客,记者可以在其中撰写和发布新闻文章。在线报纸的老板希望允许每个记者发表尽可能多的文章,但不希望不同的记者撰写同一篇文章。这意味着当读者阅读一篇文章时,他们只会看到文章中的一位作者。
例如:约翰的文章、哈利的文章、里克的文章。您不能拥有 Harry & 的文章。里克,因为老板不希望两个或更多作者写同一篇文章。
我们如何在 django 的帮助下解决这个“问题”?解决这个问题的关键是django
ForeignKey
。下面是完整的代码,可以用来实现我们老板的想法。
运行 python manage.pysyncdb 来执行 sql 代码并在数据库中为您的应用构建表。然后使用 python manage.py shell 打开 python shell。
创建报告者对象 R1。
创建文章对象 A1。
然后使用下面的代码来获取记者的姓名。
现在通过运行以下 python 代码创建 Reporter 对象 R2。
现在尝试将 R2 添加到 Article 对象 A1。
它不起作用,您将收到一个 AttributeError 消息,指出“Reporter”对象没有属性“add”。
正如您所看到的,一篇 Article 对象不能与多个 Reporter 对象相关。
R1呢?我们可以附加多个 Article 对象吗?
这个实际例子向我们展示了 django
ForeignKey
用于定义多对一关系。OneToOneField
用于创建一对一关系。我们可以在上面的 models.py 文件中使用reporter = models.OneToOneField(Reporter),但它在我们的示例中没有用,因为作者无法发布多于一篇文章。
每次您想要发布新文章时,您都必须创建一个新的 Reporter 对象。这很耗时,不是吗?
我强烈建议尝试使用
OneToOneField
的示例并意识到其中的差异。我非常确定,在这个示例之后,您将完全了解 djangoOneToOneField
和 djangoForeignKey
之间的区别。The best and the most effective way to learn new things is to see and study real world practical examples. Suppose for a moment that you want to build a blog in django where reporters can write and publish news articles. The owner of the online newspaper wants to allow each of his reporters to publish as many articles as they want, but does not want different reporters to work on the same article. This means that when readers go and read an article they will se only one author in the article.
For example: Article by John, Article by Harry, Article by Rick. You can not have Article by Harry & Rick because the boss does not want two or more authors to work on the same article.
How can we solve this 'problem' with the help of django? The key to the solution of this problem is the django
ForeignKey
.The following is the full code which can be used to implement the idea of our boss.
Run
python manage.py syncdb
to execute the sql code and build the tables for your app in your database. Then usepython manage.py shell
to open a python shell.Create the Reporter object R1.
Create the Article object A1.
Then use the following piece of code to get the name of the reporter.
Now create the Reporter object R2 by running the following python code.
Now try to add R2 to the Article object A1.
It does not work and you will get an AttributeError saying 'Reporter' object has no attribute 'add'.
As you can see an Article object can not be related to more than one Reporter object.
What about R1? Can we attach more than one Article objects to it?
This practical example shows us that django
ForeignKey
is used to define many-to-one relationships.OneToOneField
is used to create one-to-one relationships.We can use
reporter = models.OneToOneField(Reporter)
in the above models.py file but it is not going to be useful in our example as an author will not be able to post more than one article.Each time you want to post a new article you will have to create a new Reporter object. This is time consuming, isn't it?
I highly recommend to try the example with the
OneToOneField
and realize the difference. I am pretty sure that after this example you will completly know the difference between djangoOneToOneField
and djangoForeignKey
.OneToOneField(一对一)在面向对象中实现了组合的概念,而ForeignKey(一对多)则与聚合相关。
OneToOneField (one-to-one) realizes, in object orientation, the notion of composition, while ForeignKey (one-to-many) relates to agregation.
此外,
OneToOneField
可用作主键以避免键重复。可能没有隐式/显式自动字段,而是使用
OneToOneField
作为主键(例如,想象一下UserProfile
模型):Also
OneToOneField
is useful to be used as primary key to avoid key duplication. One may do not have implicit / explicit autofieldbut use
OneToOneField
as primary key instead (imagineUserProfile
model for example):我也对这两个字段的用法感到困惑。
让我举一个例子来理解它们的用法,因为我最近遇到了这个问题并意识到这两个字段的用法。
我有一个模型,像这样 -
现在的问题是我无法使用同一用户创建多个对象,
即同一用户将出席多天。因此,多个对象具有同一用户。
但 OneToOne 字段不允许我这样做。
参考图片
因此,我将模型更改为 -
现在它工作正常,我可以标记出勤率多天的用户。
这就是区别所在,OneToOne 字段不允许您使用同一用户创建多个对象(作为示例),但使用foreignkey 则可以。
I have also been confused with the usage of both the fields.
Let me give an example for understanding their usage, as I have faced the problem recently and realised the usage of both the fields.
I had a model, like this-
Now the problem with this was that I can't make multiple objects with the same user,
i.e. a same user will have attendance on multiple days. Hence, multiple objects with same user.
But the OneToOne field didn't let me do that.
Image for reference
So, I changed my model to-
Now it works fine and I can mark attendance for a user on multiple days.
So that's where the difference is, OneToOne field will not allow you to make multiple objects with the same user(as an example) but with ForeignKey it is possible.
当您访问 OneToOneField 时,您将获得查询的字段的值。在此示例中,书籍模型的“标题”字段是 OneToOneField:
当您访问外键时,您将获得相关的模型对象,然后您可以对其执行进一步的查询。在此示例中,同一本书模型的“publisher”字段是一个ForeignKey(与Publisher类模型定义相关):
使用ForeignKey字段查询也可以以另一种方式工作,但由于关系的非对称性质,它们略有不同。
在幕后,book_set 只是一个 QuerySet,可以像任何其他 QuerySet 一样进行过滤和切片。属性名称 book_set 是通过将小写模型名称附加到 _set 生成的。
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:
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):
With ForeignKey fields queries work the other way too, but they're slightly different due to the non-symmetrical nature of the relationship.
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.
OneToOneField:如果第二个表与表2相关
,则将仅包含与表1的pk值相对应的一条记录,即table2_col1将具有等于表的pk的唯一值,
表2可能包含与表1的pk值相对应的多个记录。
OneToOneField: if second table is related with
table2 will contains only one record corresponding to table1's pk value, i.e table2_col1 will have unique value equal to pk of table
table2 may contains more than one record corresponding to table1's pk value.
绘制项目之间关系的最简单方法是用简单的语言理解它们。示例
一个用户可以拥有多辆汽车,但一辆车只能有一个车主。建立此后,外键应用于具有多个关系的项目。在这种情况下,汽车。这意味着您将在汽车中包含用户作为外键
,并且一对一的关系非常简单。说一个人,一个心。一个人只有一颗心,一颗心只能属于一个人
The easiest way to draw a relationship between items is by understanding them in plain languages. Example
A user can have many cars but then a car can have just one owner. After establishing this, the foreign key should be used on the item with the many relationship. In this case the car. Meaning you'll include user as a foreign key in cars
And a one on one relationship is quite simple. Say a man and a heart. A man has only one heart and a heart can belong to just one man
OneToOneField(示例:一辆车有一个车主)
foreignKey(OneToMany)(例如:一家餐厅有很多商品)
OneToOneField (Example: one car has one owner)
ForeignKey(OneToMany) (Example: one restaurant has many items)
foreignKey 允许您接收子类(它是另一个类的定义),但 OneToOneFields 不能执行此操作,并且它不能附加到多个变量
ForeignKey allows you receive subclasses is it definition of another class but OneToOneFields cannot do this and it is not attachable to multiple variables
OneToOneField() 无法使用
_set
而 ForeignKey() 和ManyToManyField() 可以。 *您可以看到 我的问题和关于它的答案。例如,您有
Person
模型和带有OneToOneField()
的PersonDetail
模型,如下所示:然后,您无法访问子模型
PersonDetail
与Person
对象的persondetail_set
如下所示,因为存在错误。 *在OneToOneField()
的情况下,使用persondetail
而不是persondetail_set
来访问子模型PersonDetail
:现在,您使用
ForeignKey()
和ManyToManyField()
如下所示:然后,您可以使用
persondetail_set
访问子模型PersonDetail
Person
对象的 code> 如下所示:OneToOneField() cannot access the child model with
_set
while ForeignKey() and ManyToManyField() can. *You can see my question and the answer about it.For example, you have
Person
model andPersonDetail
model withOneToOneField()
as shown below:Then, you cannot access the child model
PersonDetail
withpersondetail_set
of aPerson
object as shown below because there is error. *Usepersondetail
instead ofpersondetail_set
to access the child modelPersonDetail
in this case ofOneToOneField()
:Now, you use
ForeignKey()
andManyToManyField()
as shown below:Then, you can access the child model
PersonDetail
withpersondetail_set
of aPerson
object as shown below: