你們好,我是言淦,我今天帶來的文章是《Django4-一對一,一對多,多對多關係》,但願能給大家帶來幫助!python
環境: Django 2.2.1 + Python 3.6.7sql
顯然,關係型數據庫的強大之處在於各表之間的關聯關係。 Django提供了定義三種最多見的數據庫關聯關係的方法:一對一,一對多,多對多。shell
典型的例子有一個學生對應一張身份證, 一張身份證對應一個學生。 又或者Dj文檔的例子, 一個地點(Place)對應一個餐廳(Restaurant)。在Dj中,一對一關係使用OneToOneField來關聯, 關聯後,地點表能夠查詢餐廳表的數據,餐廳表也能夠查詢地點表的數據。數據庫
例子: docs.djangoproject.com/zh-hans/2.2…django
典型的例子有一個班級擁有多個學生, 一個學生只能屬於某個班級。 又或者Dj文檔的例子, 一個做者(Reporter)能夠寫多篇文章(Article),而一篇文章只屬於一個做者。在Dj中,一對多關係使用ForeignKey來關聯。bash
注意, 正向查詢是文章表來查做者表的數據, 反向查詢是做者表來查文章表的數據。測試
官方文檔demo測試spa
# R表->R表, A表->A表
# 新建應用associatest, 假定應用已註冊
$ python manage.py makemigrations associatest
# 新建Model(與官方文檔一致)
https://docs.djangoproject.com/zh-hans/2.2/topics/db/examples/many_to_one/
# 數據遷移效果(makemigrations+sqlmigrate+migrate)
1.表名是」應用名_Model名「的形式, 好比associatest_reporter
2.若是沒有聲明主鍵,則會自動加上主鍵,主鍵名爲id
3.A表的外鍵名是reporter_id, 與R表的主鍵(id)關聯
# R表增長數據(不會受到A表的影響)
$ python manage.py shell
>>> from associatest.models import Reporter
>>> r = Reporter(first_name='John', last_name='Smith', email='john@example.com')
>>> r.save()
>>> r2 = Reporter(first_name='Paul', last_name='Jones', email='paul@example.com')
>>> r2.save()
# A表增長數據(會受到R表的影響,對應的reporter要存在)
>>> from associatest.models import Article
>>> from datetime import date
>>> a = Article(id=None, headline="test", pub_date=date(2005, 7, 27), reporter=r)
>>> a.save()
# R表篩選數據,獲得是一個queryset(條件是A表的字段)
>>> Reporter.objects.filter(article=1)
<QuerySet [<Reporter: John Smith>]>
>>> Reporter.objects.filter(article__headline='test')
<QuerySet [<Reporter: John Smith>]>
# A表篩選數據
>>> Article.objects.filter(reporter__first_name='John')
<QuerySet [<Article: test>]>
# R表查詢A表數據(filter獲得的是一個queryset, get獲得的是一個對象)
>>> r3 = Reporter.objects.get(first_name='John')
>>> r3.Article__set().get(headline='test').id
# A表查詢R表數據
>>> a.reporter.first_name
'John'
>>> a.reporter.id
1
# 字段參數
- to_field: 默認狀況下reporter字段會關聯到R表的主鍵,但能夠經過to_field指定R表的其餘字段,前提是指定的字段必須是unique的。
- related_name: 指定反向查詢用的字段, 反向查詢指R表查A表, 默認字段是Article__set()。 若是不但願反向查詢,可將related_name賦值爲'+'。
- on_delete: 指定外鍵被刪除時的一些行爲
- on_delete=CASCADE: 默認選項, 級聯刪除(可是model.delete方法是不會刪除關聯model的數據的,詳情查看官方文檔)
- PROTECT: 保護模式,若是採用該選項,刪除的時候,會拋出ProtectedError錯誤。
- SET_NULL: 置空模式,刪除的時候,外鍵字段被設置爲空,前提就是blank = True, null = True, 定義該字段的時候,容許爲空。
- SET_DEFAULT: 置默認值,刪除的時候,外鍵字段設置爲默認值,因此定義外鍵的時候注意加上一個默認值。
- SET(): 自定義一個值,該值固然只能是對應的實體了
- DO_NOTHING: 不作任何事
- db_column: reporter做爲A表的外鍵, 其在數據表的字段名稱會被命名爲reported_id(加後綴_id),若是你想避免這種狀況, 能夠用db_column參數指定字段名稱。
複製代碼
典型的例子是一個老師能夠教多個班級, 一個班級能夠被多個老師教。又或者Dj文檔的例子, 一個出版社(Publication)能夠發佈多篇文章(Article),而一篇文章能夠被多個出版社發佈。在Dj中,多對多關係使用ManyToManyField來關聯。code
docs.djangoproject.com/zh-hans/2.2…對象
Django關係模型只公開上述三種模型, OneToOneRel, ManyToOneRel, ManyToManyRel 是這三者內部使用的類。
Django_外鍵查詢和反向查詢: www.jianshu.com/p/20e078a71…
Django外鍵字段參數: docs.djangoproject.com/zh-hans/2.2…