こんにちは、最近腰痛が気になるゴマ太郎です。
本日は Django モデルの ForeignKey について解説します。
1. ForeignKey とは
1-1. モデルを紐づけるリレーションフィールド
ForeignKey は Django のモデル間を紐づけるリレーションフィールドの一つです。
Django のモデルには以下の3種類のリレーションフィールドが用意されており、それらの違いはモデルデータ間の関係性にあります。
各フィールドが使用される場面の例も【大学】をテーマに挙げてみます。
フィールド名 | 関係性 | 使用例 |
---|---|---|
ForeignKey | 一対多 | 学科 - 学科の在籍学生 |
ManyToManyField | 多対多 | 講義 - 講義の履修学生 |
OneToOneField | 一対一 | 学生 - 学生のロッカー番号 |
ちなみに今回扱うのは ForeignKey だけですが、ManyToManyField と OneToOneField についても後日解説いたします。
1-2. ForeignKey は「一対多」の関係を持たせる
ForeignKey の「一対多」とは何を意味するのか説明します。
そんなの知っとるわという方は読み飛ばしてください。
前節では「学科 - 学科の在籍学生」という例を挙げました。この場合は学科が【一】、学生が【多】となります。
『学生Aさんの学科は?と聞かれたら回答は必ず一つだけであるのに対して、情報学科の学生は?のように聞かれると回答の該当学生が複数いる。』
言ってしまうとこのようなモデルの関係が「一対多」です。
ちなみに、このとき【多】のほうは「複数になってもよいもの」であって、実際は1つだけもしくは NULL でも問題ありません。
ここからは実際に「学科 - 学科の在籍学生」の例で ForeignKey の使用方法を紹介していきます。
2. 前提条件
2-1. 環境
- Ubuntu 20.04 LTS on WSL2
- VSCode 1.76.0
- Docker Engine 23.0.1
- PostgreSQL 14.4
- Python 3.10.8
- Django 4.1.5
3. ForeignKey の使い方
3-1. models.py での書き方
ForeignKey を使うには以下のように書きます。
from django.db import models class Department(models.Model): name = models.CharField(max_length=30) class Student(models.Model): name = models.CharField(max_length=30) department = models.ForeignKey(Department, on_delete=models.CASCADE)
ここで ForeignKey に関係している記述は以下の行になります。
Student モデルの フィールドに、 モデルをセットしています。
department = models.ForeignKey(Department, on_delete=models.CASCADE)
フィールド名 = models.ForeignKey(紐づけたいモデル, on_delete=このあと紹介します)
3-2. 管理サイトで確認
確認に必要なコードの追記
ここからは ForeignKey が追加できていることを管理サイトで確認していきます。
その準備としていくつか追記します。
from django.contrib import admin from .models import Department, Student class StudentAdmin(admin.ModelAdmin): list_display = ('name', 'department') admin.site.register(Department) admin.site.register(Student, StudentAdmin)
from django.contrib import admin from django.urls import path urlpatterns = [ path('admin/', admin.site.urls), ]
python manage.py makemigrations
python manage.py migrate
管理サイト
管理サイト~/admin/にアクセスすると、 Department と Student が追加されています。
学科データをここで登録します。
学科の登録が完了すると一覧画面でデータが追加されていることが確認できます。
次に Student に移動し、学生データを登録します。
学生データ登録画面には、 Name と Department のフィールドがあり、 Department の選択肢に先ほど登録した学科が入っていれば ForeignKey の実装は成功です。
ちなみにプルダウン右側の+でも学科を追加することができます。
複数名の学生を同じ学科に紐づけられていることが確認できます。
このようにForeignKey を実装すると、モデル間の「一対多」の紐づけが可能になります。
3-3. on_delete の種類
on_delete 属性は、 ForeignKey などのリレーションフィールドが参照している親(学科)データを削除したい際の、紐づいている子(学生)データへのアクションを指定します。
設定 | データ削除時の動作 |
---|---|
CASCADE | 削除する学科データに紐づく学生データも削除する。 |
PROTECT | 他のデータに紐づいていれば削除できない。 |
RESTRICT | 削除できずエラーが表示される。 学科データを削除した際、紐づく学生データは削除されずに残る。 |
SET_NULL | 削除される学科データの代わりに NULL がセットされる。 |
SET_DEFAULT | 削除される学科データの代わりにデフォルト値がセットされる。 |
SET() | 削除される学科データの代わりに指定したデータがセットされる |
4. 最後に
今回は Django での ForeignKey の実装方法を解説しました。説明していない内容もまだまだありますので、気になった方は Django 公式ドキュメント をご確認ください。ここまで読んでいただきありがとうございました。
次回 ManyToManyField 編もよろしくお願いいたします。お疲れ様でした!
5. 参考
docs.djangoproject.com