參考資料以下html
ForeignKey
用於多對一關係,直接對應到數據庫外鍵的概念。使用ForeignKey
須要指定引用的目標表,會自動關聯到目標表的主鍵(通常是id
字段)。python
例子以下。sql
from django.db import models class Child(models.Model): parent = models.ForeignKey('Parent', on_delete=models.CASCADE, ) # ... class Parent(models.Model): # ... pass
對比之 sqlalchemy,一行parent=models.ForeignKey(...)
包含了 sqlalchemy 中的ForeignKey
和relationship
兩部份內容。數據庫
on_delete
意爲當ForeignKey
引用的對象被刪除時進行的操做。django
有幾個能夠考慮的選項。後端
CASCADE
意爲級聯,on_delete
設置爲CASCADE
時意爲執行級聯刪除。依據文檔,Django 會模仿 SQL 的ON DELETE CASCADE
,對包含了ForeignKey
的對象執行刪除。app
須要注意的是不會調用被級聯刪除對象上的model.delete()
,可是會發送pre_delete
和post_delete
信號。post
PROTECT
意爲保護,on_delete
設置爲PROTECT
意味着要阻止刪除操做發生。刪除關聯的對象時,ForeignKey
的on_delete
設置爲PROTECT
會觸發ProtectedError
。code
如其名所述,若是這個ForeignKey
是 nullable 的,則關聯的對象刪除時將外鍵設置爲 null。orm
如其名所述,若是這個ForeignKey
設置了DEFAULT
,則關聯的對象刪除時設置這個外鍵爲DEFAULT
值。
在關聯的對象刪除時,設置爲一個指定的值。這個參數能夠接受一個能夠賦值給這個 ForeignKey 的對象或者一個可調用對象。
官方例子以下。
from django.conf import settings from django.contrib.auth import get_user_model from django.db import models def get_sentinel_user(): return get_user_model().objects.get_or_create(username='deleted')[0] class MyModel(models.Model): user = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.SET(get_sentinel_user), )
應該不用多說了吧。Django 不會作多餘的事情,可是若是後端的數據庫服務有強制完整性約束,除非你在數據庫一端本身定義了ON DELETE
,不然會觸發IntegrityError
。
強制約束爲 django.admin 或者 ModelForm 渲染時提供有限的可選項。
接受參數爲dict
或者Q
對象、返回Q
對象的可調用對象。
官方例子。
staff_member = models.ForeignKey( User, on_delete=models.CASCADE, limit_choices_to={'is_staff': True}, )
Q 對象是什麼玩意兒這個我搞明白了再說...
設置反向關聯的字段名,和sqlalchemy
的backref
相似。
舉例來講。
class Child(models.Model): parent = models.ForeignKey('Parent') class Parent(models.Model): pass Parent.child_set.all() # 未設置 related_name Parent.children.all() # 設置 related_name=children
related_query_name 和 related_name 相似,設置反向引用查詢時條件的前綴名。舉例來講。
class Child(models.Model): parent = models.ForeignKey('Parent') name = models.CharField(max_length=4) class Parent(models.Model): pass Parent.objects.filter(Child__name='沙雕網友') # 未設置 related_query_name Parent.objects.filter(myboy__name='沙雕網友') # 設置 related_query_name=myboy
獲得ForeignKey
關聯的模型的字段,默認是主鍵,若是指定的不是主鍵那麼必須有unique
約束才行。
要不要建立數據庫層級的約束,也就是經過後端數據庫服務確保數據完整性不受破壞。若是設置爲 False 那麼訪問不存在的對象時會觸發 DoesNotExists 異常。
用於處理「我有一個抽象類模型可是這個模型有一個外鍵」的狀況,典型就是AUTH_USER_MODEL
。
通常不用改到,這個屬性控制了數據庫遷移時如何處理這個外鍵關聯的表,總之保持默認值就好了。
這個功能支持了使用自定義的用戶模型替代 django.auth.models.User
之類的玩意兒。
OneToOneField
基本就是一個加了unique
約束的ForeignKey
。使用上與 ForeignKey 略有不一樣。
首先是訪問 OneToOneField
時,獲得的不是 QuerySet
而是一個對象實例。
# 優生優育政策( class Parent(models.Model): child = OneToOneField('Child') class Child(models.Model): pass parent.child # => 獲得一個 Child 實例
其次是反向引用的名字是模型名字小寫。
child.parent # => 獲得一個 Parent 實例
若是指定 related_name
那就和 ForeignKey
一個表現。
基本和ForeignKey
相同。
ForeignKey
相同的參數limited_choices_to 在指定自定義中間表的狀況下無效。
用於處理一個表本身對本身的多對多引用對稱性。
Django 的默認行爲是,我是你的朋友,那麼你就是個人朋友。
設置了這個參數則強迫 Django 改變這個行爲,容許「被朋友」。
默認狀況下,Django 會自行建立中間表,這個參數強制指定中間表。
默認中間表模型裏包含三個字段。
若是是本身和本身的多對多關係,則
當自行指定中間表,中間表又包含了多個外鍵時,指定關聯的外鍵用。
舉例。
class ModelA(models.Model): b = models.ManyToManyField(ModelB, through='ModelC') class ModelB(models.Model): pass class ModelC(models.Model): a=models.ForeignKey('ModelA') b=models.ForeignKey('ModelB') c=models.ForeignKey('ModelA')
此時在中間表中a
和c
都是對ModelA
的外鍵,產生了歧義,Django 沒法自行決定用哪一個外鍵來關聯 AB 兩個表。
這時提供參數。
b = models.ManyToManyField('ModelB', through='ModelC', through_fields=(a, b))
ManyToManyField
關聯兩個表老是不對稱的關係(指我把你當兄弟,你卻想當我爸爸這樣的關係。此時「我」對「你」的「兄弟」關係就是單向的。),這就造成了來源和目標的概念。
through_fields
的第一個元素總被認爲是來源字段,第二個元素是目標字段。
指定 Django 建立的中間表的名字,默認根據兩個表表名和 ManyToManyField
的名字決定。