Django Logo

[Django]on_deleteの使い方まとめ

Django 2.0 から必須になった on_delete の使い方について、毎回調べるのも面倒なのでまとめました。 on_delete はモデル同士を紐付ける時に利用する「 ForeignKey 」「 OneToOneField 」に設定します。

on_delete とは

on_delete とは、参照するオブジェクトが削除された時に、それらと紐付けされたオブジェクトの振る舞いをどうするかを設定するものになります。 on_delete の設定には下記の6つのいずれかが設定可能です。

  • CASCADE : 関連付けられているオブジェクトを全て削除する
  • PROTECT : 関連付けられているオブジェクトがあると削除できない
  • SET_NULL : NULLがセットされる
  • SET_DEFAULT : デフォルト値がセットされる
  • SET() : 削除時の処理を自由に設定できる
  • DO_NOTHING : 何もしない

では、一つずつ使用例を元に説明していきたいと思います。

こちらのモデルを元に説明していきます。 ForeignKey を使用して、 Music オブジェクト(音楽)は Author オブジェクト(作者)を参照しています。

# models.py
from django.db import models

class Author(models.Model):
    """
    作者
    """
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class Music(models.Model):
    """
    曲
    """
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    title = models.CharField(max_length=50)

    def __str__(self):
        return self.title

Music テーブルのデータは以下のようになります。
Django on_delete 1

CASCADE

削除するオブジェクトに紐付いたオブジェクトを全て削除します。例えば、以下の画像のように Author オブジェクト(作者)の「ショパン」を削除しようとして削除ボタンをクリックすると
Django on_delete 2

関連付けられているオブジェクトを削除します」とメッセージが出るので、「はい」をクリックすると、 Author オブジェクト(作者)の「ショパン」が削除されるのと同時に、それに紐付いた Music オブジェクト(音楽)も全て削除されます。
Django on_delete 3

PROTECT

author = models.ForeignKey(Author, on_delete=models.PROTECT)

関連付けられているオブジェクトがあると削除できません。

CASCADE を設定した時と同じように削除ボタンをクリックすると「削除できません」とメッセージが表示されます。
Django on_delete 4

SET_NULL

author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True)

オブジェクトが削除されると、代わりに NULL がセットされます。 author フィールドには「 null=True 」を設定しておく必要があります。

Author の「ショパン」削除後
Django on_delete 5

SET_DEFAULT

author = models.ForeignKey(Author, on_delete=models.SET_DEFAULT, default=Author.objects.get(name='不明').pk)

オブジェクトが削除されると、代わりにデフォルト値がセットされます。 author フィールドにはデフォルト値を設定しておく必要があります。

このように author フィールドにデフォルト値の「不明」が入ります。
Django on_delete 6

SET()

def get_delete_msg():
    return Author.objects.get_or_create(name='作者が削除されました')[0].pk

class Music(models.Model):
    """
    曲
    """
    author = models.ForeignKey(Author, on_delete=models.SET(get_delete_msg()))
    title = models.CharField(max_length=50)

自分で処理を自由に設定することができます。今回は、「作者が削除されました」というメッセージを author フィールドに設定する処理を実行します。
Django on_delete 7

DO_NOTHING

なんの処理もしません。

最後に

Django 2.0 から on_delete の設定が必須なったので、それぞれの設定の特徴をしっかり把握して、効率的に開発できるようにしていきたいと思います。誤った設定をしていると、意図せずデータが削除されたり、削除したいのに削除できなかったりするケースも出てくると思うので気を付けましょう。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です