【Django】on_deleteは何をするのか。
何ついて話す?
DjangoでRESTfulなAPIを開発中です。そんな中models.pyでのモデル記述において、ForeignKeyフィールドを使う際には必ずon_delate引数をしていなければいけません。デフォルトではCASCADEになっているので何となくそのままCASCADEにしがちですが、ちゃんとコイツの意味を知らない思い通りのデータベースを構築できないと気づいたので話します。
on_delate
on_deleteは例えばmodels.pyの以下のような場面で登場します。
class UserLike(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) artist = models.CharField(max_length=16)
userフィールドはUserスキーマとのリレーションフィールドになっています。そしてon_deleteが指定されています。
on_deleteとはリレーションとして繋がっている先(つまりUserスキーマ側)のユーザーデータが削除された時に、UserLikeスキーマ側のデータをどうするかの挙動を示す引数なのです。
この値にはいくつかの種類があります。いくつか基本的なものを紹介します。
SET_NULL
SET_NULLはリレーション先のデータが削除されると、こちら側のデータは残り、リレーションとして紐づいていたフィールドだけがNULL値になります。例えば以下の例では、、、
class MatchingLog(models.Model): user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True) teacher = models.ForeignKey(Stylist, on_delete=models.CASCADE) datetime = models.DateTimeField() rate = models.ImageField(blank=True, choices=RATE_CHOICES)
これはユーザーと家庭教師のマッチングアプリのモデル(?)ですが、例えばユーザーのデータが退会などで削除されても、家庭教師のレイティングは削除されて欲しくないのでon_deleteをSET_NULLにして置くことで、ユーザーの値はNULLになってデータは残ります。こういう時に使えます。
ちなみにSET_NULLに設定するにはnull=Trueという引数も指定し、そのフィールドでNULL値を使うことを許可しなくてはいけないです。
PROTECT
PROTECTを指定すると、リレーションとして紐づいているデータがあれば削除ができないようにできます。例えば上記の家庭教師マッチングアプリの場合、一度マッチングをし、MatchingLogスキーマ側から参照されたユーザーデータは削除ができなくなります。一度もマッチングをせず、MatchingLogスキーマ側のデータと全く紐づいていないユーザーデータは削除できます。
SET_DEFAULT
SET_DEFAULTはリレーション先のデータが削除されると、default引数に指定しておいた値が削除されたデータの代わりに入るようになっています。
class Food(models.Model): name = models.CharField(max_length=16) category = models.ForeignKey(Category, on_delete=models.SET_DEFAULT, default=Category.objects.get(name='中華'))
上記の例の場合、例えば’和食’というカテゴリーが削除されれば、そこに紐づけられていた食品はずべてデフォルトに設定していた'中華'のカテゴリーになります。めちゃくちゃですが.....
参考記事
Django、on_deleteを使う(django2.0から必須)
narito.ninja