Agile育成ブログ
未来を変える喜びを
Django

on_deleteオプション


Warning: count(): Parameter must be an array or an object that implements Countable in /home/xs638785/agile-software.site/public_html/wp-content/plugins/rich-table-of-content/functions.php on line 490

モデル同士を紐づけるときに、ForeignKeyOneToOneFieldを使いますが、その際、バージョン2からは引数としてon_deleteを指定することが必須となりました。

on_deleteとは、参照するオブジェクトが削除されたときに、それと紐づけられたオブジェクトも一緒に削除するのか、それともそのオブジェクトは残しておくのかを設定するものです。

on_deleteオプション
models.CASCADE一緒に削除される
models.PROTECT削除できない
models.SET_NULLNULLがセットされる
models.SET_DEFAULTデフォルト値がセットされる
models.SET任意の値がセットされる
DO_NOTHING何もしない

使用例

from django.db import models

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

    def __str__(self):
        return self.name

class Story(models.Model):
    """小説"""
    author = models.ForeignKey(Author, on_delete=models.CASCADE)
    title = models.CharField(max_length=50)
    text = models.TextField()

    def __str__(self):
        return self.title

この設計によってこんなStorysテーブルができます。

例えばここでAuthorオブジェクト:”川端康成”を削除したときに、それと紐づいたStoryオブジェクト:”雪国”、”伊豆の踊り子”も削除するのか、それとも残しておくのかを設定するのがon_deleteです。

CASCADE

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

削除するオブジェクトに紐づいたオブジェクトを全て削除します。

例えば、以下の画像のようにAuthorオブジェクト”川端康成”を削除しようとして削除ボタンを押すと、

このように「関連付けられてるオブジェクトを削除します」とメッセージが出ます。

「はい」ボタンで、Authorオブジェクト”川端康成”が削除されるのと同時に、それに紐づいたStoryオブジェクトも全て削除されます。

PROTECT

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

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

この場合、Authorに紐づいたStoryがあるのでAuthorを削除することができません。関連付けられたStoryオブジェクトを全て削除すればAuthorも削除することができるようになります

SET_NULL

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

オブジェクトが削除されると、代わりにNULLをセットします。

今回の例だと、Authorを削除するとStoryオブジェクトのauthorフィールドがNULL(空白)になります。

こんな感じで、Authorに誰も登録されていない状態になります。注意点として、authorフィールドはnull=Trueにしておく必要があります。

 SET_DEFAULT

author = models.ForeignKey(
    Author,
    on_delete=models.SET_DEFAULT,
    default=Author.objects.get(name="匿名")
)

削除されたオブジェクトの代わりに、デフォルト値が入るようになります。注意点として、authorフィールドにはデフォルト値を設定しておく必要があります。

このようにauthorフィールドにデフォルト値の”匿名”が入ります

SET()

自分で処理を自由に設定することができます。

今回は、”削除された著者”という文字列をauthorフィールドに入れる処理をします

def get_deleted_user():
    return Author.objects.get_or_create(name="削除された作者")[0]

class Story(models.Model):
    author = models.ForeignKey(Author, on_delete=models.SET(get_deleted_user))
    title = models.CharField(max_length=50)
    text = models.TextField()

DO_NOTHING

何の処理もしません。

You cannot copy content of this page