Django中外鍵使用總結(jié)
在寫項目的過程中我們不可避免的會使用到外鍵這個東西,那么Django中是怎樣來使用外鍵的呢?
了解外鍵
在MySQL中,表有兩種引擎,一種是InnoDB,另外一種是myisam。如果使用的是InnoDB引擎,是支持外鍵約束的。外鍵的存在使得ORM框架在處理表關(guān)系的時候異常的強大。MySQL數(shù)據(jù)庫默認使用的也是InnoDB引擎。
使用外鍵
新建一個項目,創(chuàng)建一個article的app,添加至settings中,并且在settings中設(shè)置數(shù)據(jù)庫的連接,調(diào)至整個項目能運行為止。
類定義為class ForeignKey(to,on_delete,**options)。第一個參數(shù)是引用的是哪個模型,第二個參數(shù)是在使用外鍵引用的模型數(shù)據(jù)被刪除了,這個字段該如何處理,比如有CASCADE、SET_NULL等(外鍵刪除各個參數(shù)的意思)。這里以一個實際案例來說明。比如有一個Category和一個Article兩個模型。一個種類下可以包含多篇文章,一個Article只能有一個種類,并且通過外鍵進行引用。那么相關(guān)的示例代碼如下:
在同一個app中使用外鍵
在article中的models中寫入代碼:
from django.db import models # Create your models here. class Category(models.Model): ? ? name = models.CharField(max_length=100) class Article(models.Model): ? ? title = models.CharField(max_length=100) ? ? content = models.TextField() ? ? # 是由Category影響Article ? ? category = models.ForeignKey('Category',on_delete=models.CASCADE)
這里我們就在Article中設(shè)置了一個外鍵category。
以上使用ForeignKey來定義模型之間的關(guān)系。即在article的實例中可以通過category屬性來操作對應(yīng)的Category模型。這樣使用起來非常的方便。示例代碼如下:views中寫入
from django.shortcuts import render from . import models from django.http import HttpResponse # Create your views here. def index(request): ? ?? ? ? # 插入數(shù)據(jù) ? ? # article = models.Article(title='abc',content='111') ? ? # category = models.Category(name='最新文章') ? ? # category.save() ? ? # article.category = category ? ? # article.save() ? ? #讀取數(shù)據(jù) ? ? article = models.Article.objects.first() ? ? print(article.category.name) ? ? return HttpResponse('successful')
在上面代碼中把相應(yīng)的注釋去了,就能夠進行測試了。
為什么使用了ForeignKey后,就能通過category訪問到對應(yīng)的Catrgory對象呢。因此在底層,Django為Article表添加了一個屬性名_id的字段(比如category的字段名稱是category_id),這個字段是一個外鍵,記錄著對應(yīng)的種類的主鍵。以后通過article.category訪問的時候,實際上是先通過category_id找到對應(yīng)的數(shù)據(jù),然后再提取Category表中的這條數(shù)據(jù),形成一個模型。
如果想要引用另外一個app的模型,那么應(yīng)該在傳遞to參數(shù)的時候,使用app.model_name進行指定。例如,如果User和Article不是在同一個app中,那么在引用的時候的示例代碼如下:
首先新建一個user的app,并且添加至settings中,在user中的models中寫入代碼,創(chuàng)建一個User模型
from django.db import models # Create your models here. class User(models.Model): ? ? username = models.CharField(max_length=100)
再在article中的models中添加這個外鍵,即在Article這個模型中新添加一個屬性
# 將user中的User這個模型作為外鍵 author = models.ForeignKey('user.User',on_delete=models.CASCADE,null=True)
如果模型的外鍵引用的是本身自己這個模型,那么to參數(shù)可以為self,或者是這個模型的名字。在論壇開發(fā)中,一般評論都可以進行二級評論,即可以針對另外一個評論進行評論,那么在定義模型的時候就需要使用外鍵來引用自身。示例代碼如下:
class Comment(models.Model): content = models.TextField() orihin_comment = models.ForeignKey('self',on_delete=models.CASCADE)
這樣我們就實現(xiàn)了添加了一個外鍵引用自身。
外間刪除操作的參數(shù)意思:
如果一個模型使用了外鍵。那么在對方那個模型被刪掉后,該進行什么樣的操作。可以通過on_delete來指定。可以指定的類型如下:
- CASCADE:級聯(lián)操作。如果外鍵對應(yīng)的那條數(shù)據(jù)被刪除了,那么這條數(shù)據(jù)也會被刪除。
- PROTECT:受保護。即只要這條數(shù)據(jù)引用了外鍵的那條數(shù)據(jù),那么就不能刪除外鍵的那條數(shù)據(jù)。如果我們強行刪除,Django就會報錯。
- SET_NULL:設(shè)置為空。如果外鍵的那條數(shù)據(jù)被刪除了,那么在本條數(shù)據(jù)上就將這個字段設(shè)置為空。如果設(shè)置這個選項,前提是要指定這個字段可以為空。
- SET_DEFAULT:設(shè)置默認值。如果外鍵的那條數(shù)據(jù)被刪除了,那么本條數(shù)據(jù)上就將這個字段設(shè)置為默認值。如果設(shè)置這個選項,== 前提是要指定這個字段一個默認值 ==。
- SET():如果外鍵的那條數(shù)據(jù)被刪除了。那么將會獲取SET函數(shù)中的值來作為這個外鍵的值。SET函數(shù)可以接收一個可以調(diào)用的對象(比如函數(shù)或者方法),如果是可以調(diào)用的對象,那么會將這個對象調(diào)用后的結(jié)果作為值返回回去。== 可以不用指定默認值 ==
- DO_NOTHING:不采取任何行為。一切全看數(shù)據(jù)庫級別的約束。
以上這些選項只是Django級別的,數(shù)據(jù)級別依舊是RESTRICT!
數(shù)據(jù)庫層面的約束有四種:
- RESTRICT:默認的選項,如果想要刪除父表的記錄時,而在子表中有關(guān)聯(lián)該父表的記錄,則不允許刪除父表中的記錄;
- NOACTION:同 RESTRICT效果一樣,也是首先先檢查外鍵;
- CASCADE:父表delete、update的時候,子表會delete、update掉關(guān)聯(lián)記錄;
- SET NULL:父表delete、update的時候,子表會將關(guān)聯(lián)記錄的外鍵字段所在列設(shè)為null,所以注意在設(shè)計子表時外鍵不能設(shè)為not null;
參考鏈接:http://chabaoo.cn/article/257166.htm
為什么ORM能越過數(shù)據(jù)庫的約束呢?
是因為ORM操作是反過來的,比如我們在ORM模型中設(shè)置了on_delete=models.CASCADE,那么在進行刪除的時候,如果發(fā)現(xiàn)在數(shù)據(jù)庫層面有父表約束著它,使他不能被刪除,那么ORM就會先去刪除父表,再來刪除指定的表,從而達到越過了數(shù)據(jù)庫層面的約束。
到此這篇關(guān)于Django中外鍵使用總結(jié)的文章就介紹到這了,更多相關(guān)Django 外鍵內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pytest解讀fixtures之Teardown處理yield和addfinalizer方案
這篇文章主要為大家介紹了pytest解讀fixtures之Teardown處理yield和addfinalizer的方案實例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06python神經(jīng)網(wǎng)絡(luò)學習數(shù)據(jù)增強及預處理示例詳解
這篇文章主要為大家介紹了python神經(jīng)網(wǎng)絡(luò)學習數(shù)據(jù)增強及預處理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-05-05Python爬取YY評級分數(shù)并保存數(shù)據(jù)實現(xiàn)過程解析
這篇文章主要介紹了Python爬取YY評級分數(shù)并保存數(shù)據(jù)實現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-06-06python爬取拉勾網(wǎng)職位數(shù)據(jù)的方法
這篇文章主要介紹了python爬取拉勾網(wǎng)職位數(shù)據(jù)的實現(xiàn)方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2018-01-01python selenium操作cookie的實現(xiàn)
這篇文章主要介紹了python selenium操作cookie的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-03-03