django OneToOneField和ForeignKey有什麼區別?django OneToOneField和ForeignKey有什麼區別?
回答
小心認識到OneToOneField(SomeModel)
和ForeignKey(SomeModel, unique=True)
之間有一些差異。正如The Definitive Guide to Django指出:
OneToOneField
一個一對一的關係。從概念上講,這與與
unique=True
類似,但關係的「反向」側將直接返回單個對象。
與此相反的OneToOneField
「反向」的關係,一個ForeignKey
「反向」關係返回QuerySet
。
例
例如,如果我們有以下兩個模型(下面完整模型代碼):
Car
模型使用OneToOneField(Engine)
Car2
模型使用ForeignKey(Engine2, unique=True)
從在python manage.py shell
內執行以下操作:
OneToOneField
例
>>> from testapp.models import Car, Engine
>>> c = Car.objects.get(name='Audi')
>>> e = Engine.objects.get(name='Diesel')
>>> e.car
<Car: Audi>
ForeignKey
與unique=True
例
>>> from testapp.models import Car2, Engine2
>>> c2 = Car2.objects.get(name='Mazda')
>>> e2 = Engine2.objects.get(name='Wankel')
>>> e2.car2_set.all()
[<Car2: Mazda>]
型號代碼
from django.db import models
class Engine(models.Model):
name = models.CharField(max_length=25)
def __unicode__(self):
return self.name
class Car(models.Model):
name = models.CharField(max_length=25)
engine = models.OneToOneField(Engine)
def __unicode__(self):
return self.name
class Engine2(models.Model):
name = models.CharField(max_length=25)
def __unicode__(self):
return self.name
class Car2(models.Model):
name = models.CharField(max_length=25)
engine = models.ForeignKey(Engine2, unique=True)
def __unicode__(self):
return self.name
ForeignKey是一對多的,所以一個Car對象可能有很多個車輪,每個車輪都有一個到它所屬的Car的ForeignKey。 OneToOneField就像一個引擎,一個Car對象可以只有一個。
謝謝你,劑量OneToOneField(someModel)平均ForeignKey的(SomeModel,獨特= TRUE)? – redice 2011-05-03 14:13:21
是的:'OneToOneField本質上與ForeignKey相同,除了它總是攜帶一個「唯一」約束,反向關係總是返回指向的對象(因爲只會有一個),而不是返回一個列表。' – 2011-05-03 14:18:05
幾款具有相同發動機的汽車呢? – 2013-12-04 23:04:01
OneToOneField(一到一個)實現,在面向對象,組合物的概念,而ForeignKey(一對多)涉及聚合。
當您訪問OneToOneField時,您將獲得您查詢的字段的值。在這個例子中一本書模型的「標題」字段是一個OneToOneField:
>>> from mysite.books.models import Book
>>> b = Book.objects.get(id=50)
>>> b.title
u'The Django Book'
當你訪問一個ForeignKey你會得到相關的模型對象,然後你就可以對瓶坯進一步查詢。在這個例子中,同一本書型號的「出版商」字段是一個ForeignKey(關聯到發佈服務器類模型定義):
>>> 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,可以過濾和切片像任何其他查詢集。屬性名稱book_set通過將小寫模型名稱附加到_set來生成。
學習新事物最好的和最有效的方法是看到和研究現實世界的實例。假設你想在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()
創建文章對象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
之間的區別。
另外OneToOneField
可用作主鍵來避免密鑰重複。人們可能不具有隱性/明確的自動字段
models.AutoField(primary_key=True)
但使用OneToOneField
作爲主鍵,而不是(想象一下,例如UserProfile
模型):
user = models.OneToOneField(
User, null=False, primary_key=True, verbose_name='Member profile')
- 1. Django OneToOneField或ForeignKey?
- 2. OneToOneField與ForeignKey的
- 3. Django和Python有什麼區別?
- 4. django classonlymethod和python classmethod有什麼區別?
- 5. Django和Joomla有什麼區別?
- 6. django中Model.id和Model.pk有什麼區別?
- 7. 如何使用ViewSet更新OneToOneField/ForeignKey? Django
- 8. 將Django中的模型放置在ForeignKey之間有什麼區別?
- 9. 有什麼區別`和$(Bash中有什麼區別?
- 10. ManyToOneRel和ForeignKey之間的區別?
- 11. 有什麼區別? :和||
- 12. &&和||有什麼區別?
- 13. 「/」和「/ *」有什麼區別?
- 14. 有什麼區別:。!和:r!?
- 15. ==和===有什麼區別?
- 16. Appender和〜有什麼區別?
- 17. $ @和$ *有什麼區別?
- 18. is和=有什麼區別?
- 19. #.00和#。##有什麼區別?
- 20. `==`和`is`有什麼區別?
- 21. '=='和'==='有什麼區別?
- 22. /和/#/有什麼區別?
- 23. | 0和~~有什麼區別?
- 24. `&`和`ref`有什麼區別?
- 25. ==和===有什麼區別?
- 26. ==和===有什麼區別?
- 27. `{}`和`[]`有什麼區別?
- 28. JavaScript和=== ===有什麼區別?
- 29. difftime和' - '有什麼區別?
- 30. =和==有什麼區別?
@MarkPNeyer:據我所知,OneToOne字段就是:一對一。它不一定要上。見[**這個例子**](https://docs.djangoproject.com/en/dev/topics/db/examples/one_to_one/):一個地方不一定是餐廳。 – osa 2013-12-04 20:36:13
這個答案說「有一些差異」,然後命名一個區別。有其他人嗎? – 2014-08-06 08:35:30
我想和克里斯一樣。它僅僅是語法糖,數據訪問方式是否存在一些根本性差異,導致性能差異? – Carlos 2014-08-10 13:16:02