外來鍵
在MySQL
中,表有兩種引擎,一種是InnoDB
,另外一種是myisam
。如果使用的是InnoDB
引擎,是支援外來鍵約束的。外來鍵的存在使得ORM
框架在處理表關係的時候異常的強大。因此這裡我們首先來介紹下外來鍵在Django
中的使用。
類定義為class ForeignKey(to,on_delete,**options)
。第一個引數是引用的是哪個模型,第二個引數是在使用外來鍵引用的模型資料被刪除了,這個欄位該如何處理,比如有CASCADE
、SET_NULL
等。這裡以一個實際案例來說明。比如有一個User
和一個Article
兩個模型。一個User
可以發表多篇文章,一個Article
只能有一個Author
,並且通過外來鍵進行引用。那麼相關的示例程式碼如下:
class User(models.Model):
username = models.CharField(max_length=20)
password = models.CharField(max_length=100)
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
author = models.ForeignKey("User",on_delete=models.CASCADE)
以上使用ForeignKey
來定義模型之間的關係。即在article
的例項中可以通過author
屬性來操作對應的User
模型。這樣使用起來非常的方便。示例程式碼如下:
article = Article(title='abc',content='123')
author = User(username='張三',password='111111')
article.author = author
article.save()
# 修改article.author上的值
article.author.username = '李四'
article.save()
為什麼使用了ForeignKey
後,就能通過author
訪問到對應的user
物件呢。因此在底層,Django
為Article
表新增了一個屬性名_id
的欄位(比如author的欄位名稱是author_id),這個欄位是一個外來鍵,記錄著對應的作者的主鍵。以後通過article.author
訪問的時候,實際上是先通過author_id
找到對應的資料,然後再提取User
表中的這條資料,形成一個模型。
如果想要引用另外一個app
的模型,那麼應該在傳遞to
引數的時候,使用app.model_name
進行指定。以上例為例,如果User
和Article
不是在同一個app
中,那麼在引用的時候的示例程式碼如下:
# User模型在user這個app中
class User(models.Model):
username = models.CharField(max_length=20)
password = models.CharField(max_length=100)
# Article模型在article這個app中
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
author = models.ForeignKey("user.User",on_delete=models.CASCADE)
如果模型的外來鍵引用的是本身自己這個模型,那麼to
引數可以為'self'
,或者是這個模型的名字。在論壇開發中,一般評論都可以進行二級評論,即可以針對另外一個評論進行評論,那麼在定義模型的時候就需要使用外來鍵來引用自身。示例程式碼如下:
class Comment(models.Model):
content = models.TextField()
origin_comment = models.ForeignKey('self',on_delete=models.CASCADE,null=True)
# 或者
# origin_comment = models.ForeignKey('Comment',on_delete=models.CASCADE,null=True)
外來鍵刪除操作:
如果一個模型使用了外來鍵。那麼在對方那個模型被刪掉後,該進行什麼樣的操作。可以通過on_delete
來指定。可以指定的型別如下:
CASCADE
:級聯操作。如果外來鍵對應的那條資料被刪除了,那麼這條資料也會被刪除。PROTECT
:受保護。即只要這條資料引用了外來鍵的那條資料,那麼就不能刪除外來鍵的那條資料。SET_NULL
:設定為空。如果外來鍵的那條資料被刪除了,那麼在本條資料上就將這個欄位設定為空。如果設定這個選項,前提是要指定這個欄位可以為空。SET_DEFAULT
:設定預設值。如果外來鍵的那條資料被刪除了,那麼本條資料上就將這個欄位設定為預設值。如果設定這個選項,前提是要指定這個欄位一個預設值。SET()
:如果外來鍵的那條資料被刪除了。那麼將會獲取SET
函式中的值來作為這個外來鍵的值。SET
函式可以接收一個可以呼叫的物件(比如函式或者方法),如果是可以呼叫的物件,那麼會將這個物件呼叫後的結果作為值返回回去。DO_NOTHING
:不採取任何行為。一切全看資料庫級別的約束。