[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テーブルのデータは以下のようになります。

CASCADE

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

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

PROTECT

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

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

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

SET_NULL

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

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

Authorの「ショパン」削除後

SET_DEFAULT

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

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

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

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フィールドに設定する処理を実行します。

DO_NOTHING

なんの処理もしません。

最後に

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