Django中的OneToOneField和ForeignKey有什么区别?
当前回答
我也对这两个字段的用法感到困惑。 让我举一个例子来理解它们的用法,因为我最近遇到了这个问题,并意识到这两个字段的用法。
我有一个模型,像这样
from django.contrib.auth.models import User
from django.db import models
class Attendance(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, default="", null=True)
date = models.CharField(max_length=11)
def __int__(self):
return self.id
现在这个的问题是我不能用同一个用户创建多个对象, 也就是说,同一个用户将在多个日子里出席会议。因此,同一个用户有多个对象。
但是一对一领域不允许我这么做。 参考图片
所以我把模型改成-
from django.contrib.auth.models import User
from django.db import models
class Attendance(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, default="", null=True)
date = models.CharField(max_length=11)
def __int__(self):
return self.id
现在它工作得很好,我可以标记一个用户在多天的出席。
这就是区别所在,OneToOne字段不允许你用同一个用户创建多个对象(举个例子),但是使用ForeignKey是可以的。
其他回答
ForeignKey允许你接收子类,它是另一个类的定义,但OneToOneFields不能这样做,它不能附加到多个变量
绘制项目之间关系的最简单方法是用简单的语言理解它们。例子
一个用户可以有很多辆车,但一辆车只能有一个车主。建立此关系后,应将外键用于关系较多的项上。在这种情况下,是汽车。这意味着您将在cars中包含user作为外键
一对一的关系很简单。说一个男人和一颗心。一个人只有一颗心,而一颗心只能属于一个人
OneToOneField(一对一)在面向对象中实现了组合的概念,而ForeignKey(一对多)则与聚合有关。
此外,OneToOneField可用作主键以避免键重复。可能没有隐式/显式autofield
models.AutoField(primary_key=True)
但是使用OneToOneField作为主键(假设UserProfile模型为例):
user = models.OneToOneField(
User, null=False, primary_key=True, verbose_name='Member profile')
学习新事物的最好和最有效的方法是看和研究现实世界的实际例子。假设您想在django中构建一个博客,记者可以在这里撰写和发布新闻文章。这家在线报纸的所有者希望允许他的每个记者发表尽可能多的文章,但不希望不同的记者为同一篇文章工作。这意味着当读者去阅读一篇文章时,他们只能在文章中看到一个作者。
例如:John的文章,Harry的文章,Rick的文章。你不能有Harry & Rick的文章,因为老板不希望两个或两个以上的作者在同一篇文章上工作。
如何在django的帮助下解决这个问题?解决这个问题的关键是django的ForeignKey。
下面是完整的代码,可以用来实现我们老板的想法。
from django.db import models
# Create your models here.
class Reporter(models.Model):
first_name = models.CharField(max_length=30)
def __unicode__(self):
return self.first_name
class Article(models.Model):
title = models.CharField(max_length=100)
reporter = models.ForeignKey(Reporter)
def __unicode__(self):
return self.title
运行python manage.py syncdb来执行sql代码,并在数据库中为你的应用程序构建表。然后使用python manage.py shell打开python shell。
创建Reporter对象R1。
In [49]: from thepub.models import Reporter, Article
In [50]: R1 = Reporter(first_name='Rick')
In [51]: R1.save()
创建Article对象A1。
In [5]: A1 = Article.objects.create(title='TDD In Django', reporter=R1)
In [6]: A1.save()
然后使用下面的代码段获取报告器的名称。
In [8]: A1.reporter.first_name
Out[8]: 'Rick'
现在通过运行以下python代码创建Reporter对象R2。
In [9]: R2 = Reporter.objects.create(first_name='Harry')
In [10]: R2.save()
现在尝试将R2添加到Article对象A1。
In [13]: A1.reporter.add(R2)
它不起作用,你会得到一个AttributeError,说'Reporter'对象没有属性'add'。
正如您所看到的,一个Article对象不能与多个Reporter对象相关。
R1呢?我们可以给它附加多个Article对象吗?
In [14]: A2 = Article.objects.create(title='Python News', reporter=R1)
In [15]: R1.article_set.all()
Out[15]: [<Article: Python News>, <Article: TDD In Django>]
这个实例向我们展示了如何使用django ForeignKey来定义多对一关系。
OneToOneField用于创建一对一的关系。
我们可以在上面的models.py文件中使用reporter = models.OneToOneField(reporter),但它在我们的例子中并不有用,因为作者将无法发布多篇文章。
每次要发布一篇新文章时,都必须创建一个新的Reporter对象。这很浪费时间,不是吗?
我强烈建议您尝试使用OneToOneField的示例,并了解其中的差异。我很确定在这个例子之后,你会完全知道django OneToOneField和django ForeignKey之间的区别。
推荐文章
- django MultiValueDictKeyError错误,我如何处理它
- 我如何在Django中创建一个鼻涕虫?
- 没有名为'django.core.urlresolvers'的模块
- Django - makemigrations -未检测到任何更改
- ">", "<", ">=" 和“< =”不工作”在Django过滤()”
- Django项目工作目录结构的最佳实践
- 如何在Django中表达一对多关系?
- 用Django创建电子邮件模板
- Django的嵌套元类是如何工作的?
- 用Django实现OpenID的最佳解决方案是什么?
- 在使用信号时,你不能在'原子'块的末尾执行查询,但只能在单元测试期间执行
- Django查询- id vs pk
- render(), render_to_response()和direct_to_template()之间有什么区别?
- 如何使用MySQLdb与Python和Django在OSX 10.6?
- 如何在Django中一次添加多个对象到ManyToMany关系?