Django 模型中 On_delete 引數的作用
Django 模型簡化了資料庫和表的建立、向表中新增新資料或元組、刪除、檢索和修改。使用 Django 模型,我們可以藉助外來鍵輕鬆建立表之間的關係。
在設定關係時,我們必須為一些引數設定值。一個這樣的引數是 on_delete
。on_delete
引數用於配置刪除引用物件時應採用的行為。它基本上用於定義如何處理刪除引用物件的影響。
on_delete
引數可以配置為七種可能的行為或操作。我們將單獨討論所有這些。
CASCADE
引數
在建立模型之間的關係時,通常會使用級聯行為。當一個被引用的物件被刪除時,所有引用該被引用物件的物件也將被刪除。
語法:
XYZ = models.ForeignKey(WASD, on_delete=models.CASCADE)
為了更好地理解它,請考慮以下示例。請注意,同樣的示例也將用於解釋其他一些行為。
有一個網站,作者可以在網站上註冊自己並寫部落格。現在代表兩個實體,考慮兩個模型,即 Author
和 Blog
。Blog
中的所有條目或元組都有一個外來鍵引用(或正在引用)到 Author
條目或元組。它代表了一種關係,即每篇部落格都屬於寫它的作者。
現在,假設網站有一項政策,如果作者刪除他/她的帳戶,那麼他或她曾經寫過的所有部落格都將被刪除。在這種情況下,級聯關係將是一個恰當的選擇。
PROTECT
引數
如果存在引用此物件的物件,則 PROTECT
引數可防止刪除引用的物件。換句話說,只要引用它的物件存在,就不能刪除被引用的物件。在刪除引用物件之前,必須手動刪除引用物件。通過引發 ProtectedError
阻止刪除。
這種關係可以用在資料非常重要和敏感的地方,如果處理得當,你不能丟失它。或者當引用物件也在其他地方使用時,如果沒有適當的驗證和處理,它們就不能被刪除。
RESTRICT
引數
RESTRICT
類似於 PROTECT
。它還可以防止刪除引用的物件並引發 RestrictedError
。但兩者之間有細微的差別。與 PROTECT
不同,如果被引用的物件正在引用某個其他物件是一個 CASCADE
關係,並且它也被刪除,則允許刪除。換句話說,如果引用物件和被引用物件在 CASCADE
關係中引用了某個其他公共物件,則允許刪除引用物件。
考慮以下示例。
class Artist(models.Model):
name = models.CharField(max_length=100)
class Album(models.Model):
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
class Song(models.Model):
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
album = models.ForeignKey(Album, on_delete=models.RESTRICT)
如果我們嘗試刪除 Album
物件,則會引發 RestrictedError
。但是,如果我們嘗試刪除 Artist
物件,那麼刪除將成功,因為引用 Album
物件的歌曲也引用了 CASCADE relationship
中的 Album
物件引用的 Artist
物件。
SET_NULL
引數
在 SET_NULL
的情況下,顧名思義,當刪除一個引用物件時,所有引用物件的引用物件都設定為 NULL
。這種關係要求引用的物件欄位可以為空。
XYZ = models.ForeignKey(WASD, on_delete=models.SET_NULL, null=True)
例如,如果網站有一個政策,如果作者離開,那麼他/她的部落格不會但被刪除。相反,所有部落格的作者將被設定為匿名作者或 None
。
SET_DEFAULT
引數
在 SET_DEFAULT
的情況下,當引用物件被刪除時,所有引用物件的引用物件都會設定為預設值。這個預設值可以是 NULL
以及其他一些 Django 模型或表。這種關係要求引用的物件欄位在 NULL
的情況下可以為空。
XYZ = models.ForeignKey(WASD, on_delete=models.SET_DEFAULT, null=True, default=QWERTY)
例如,如果網站有一個政策,如果作者離開,那麼他/她所有部落格的作者將是管理員或公司本身。在這種情況下,SET_DEFAULT
將是正確的選擇。
SET()
引數
SET()
與 SET_DEFAULT
完全相同。它也可以接受 Django 模型或表格。唯一的區別是在 SET() 中,我們可以傳遞一個可呼叫物件,如果引用的物件被刪除,它將為所有引用物件呼叫。
XYZ = models.ForeignKey(WASD, on_delete=models.SET(...), null=True)
可呼叫函式和模型看起來像這樣。
def getUser():
"""Callable function"""
return User.objects.get_or_create(username="anonymous")[0]
class Author(models.Model):
user = models.ForeignKey(User, on_delete=models.SET(getUser))
DO_NOTHING
引數
DO_NOTHING
是一種可能存在於兩個模型之間的風險關係。顧名思義,當一個被引用物件被刪除時,所有引用物件的被引用物件都不會被改變。換句話說,不會做任何事情來處理刪除的影響。
這是一種非常危險的行為,因為它會導致完整性問題,因為引用的物件已被刪除,但引用的物件仍在引用它。
XYZ = models.ForeignKey(WASD, on_delete=models.DO_NOTHING)