【Django】ForeignKeyの引数で指定するrelated_nameについて
2022.03.21 /
本記事ではDjangoにおける、ForeignKeyの引数で指定できるrelated_nameについて解説してきます。
Djangoの解説サイトではForeignKeyのオプションにrelated_nameを指定していたり、指定していないフィールドがあって、どんな役割を果たしているのかわからないですよね。
related_nameは使用方法を理解するとWebアプリケーションの作成にとても役立ちます。本記事を通してぜひrelated_nameの知識を深めてください。
models.py:リレーションフィールド
リレーションフィールドとは
Djangoで利用するリレーショナルデータベースでは3つのリレーション(「一対一」、「多対一」、「多対多」)があります。
これらリレーション(関連)は以下のリレーションフィールドで定義できます。
リレーションフィールド | 関係性 |
---|---|
ForeignKey | 多対一 |
OneToOneField | 一対一 |
ManyToManyField | 多対多 |
リレーションフィールドは関連があるモデル間(テーブル間)を紐づけるために使用するということです。
各リレーションフィールドについて詳しくは以下記事をご参照ください。
【django】モデルのリレーションフィールド:ForeignKey、OneToOneField、ManyToManyField
リレーションフィールド:ForeignKey
リレーションフィールドの一つ、ForeignKeyは「多対一」の関連を持つモデル同士を関連付け(結び付け)ます。
ForeignKeyで関係付けられたモデルオブジェクト間で、関連モデルのフィールドを参照することができます。親(一側)から子(多側)のモデルを参照することを逆参照と呼びます。
ForeignKeyのフィールドが定義されていない側のモデルから、ForeignKeyが定義されているモデルを参照(逆参照)する方法は以下記事をご参照ください。
【Django】ForeignKey:一側から多側のモデルを参照(逆参照)する方法(_set)
ここで解説した逆参照は次項より解説するrelated_nameに大きく関係します。
ForeginKey:related_name
related_nameとは
models.pyでForeignKeyを指定する場合、以下の構文で記入します。
ForeignKey(to, on_delete, **options)
ForeignKeyには2つの引数(to, on_delete)を必ず指定する必要があります。toには紐づけるモデルを指定し、on_deleteには親フィールドが削除されたときの動作を指定します。
そしてrelated_nameはForeignKeyに指定できるオプションの一つです。オプションなのでrelated_nameは指定しなくても大丈夫です。
related_nameを指定することにより、逆参照する際にrelated_nameで指定した値で逆参照ができるようになります。
つまりrelated_nameを指定すると、<関連先モデルのクラス_set>ではなく、related_nameで指定した値で逆参照を行うということです。
related_nameの使用例
related_nameの使用例を紹介していきます。ここでは以下のモデルを使って解説を進めていきます。
class Dapartment(models.Model):
name = models.CharField(max_length=255)
address = models.CharField(max_length=255)
def __str__(self):
return self.name
class User(models.Model):
username = models.CharField(max_length=100, unique=True)
department = models.ForeignKey(Department, on_delete=models.CASCADE)
def __str__(self):
return self.username
上記モデルでDepartment(親)からUser(子)を_setによる逆参照する場合、次のように記述します。
>>> obj = Department.objects.get(id=1)
>>> for user in obj.user_set.all():
... print(user.username)
それでは次にrelated_nameを以下のようにForeignKeyに指定します。
class User(models.Model):
username = models.CharField(max_length=100, unique=True)
department = models.ForeignKey(Department, on_delete=models.CASCADE, related_name= "User")
def __str__(self):
return self.username
このようにForeignKeyのオプションにrelated_nameを指定すると逆参照は以下のように記述できます。
>>> obj = Department.objects.get(id=1)
>>> for user in obj.User.all():
... print(user.username)
このようにrelated_nameを使うことにより、コードのわかりやすさ・理解のしやすさが格段によくなります。
必ずrelated_nameを使用する場面
基本的にはForeignKeyのオプションにrelated_nameは指定しなくてもいいのですが、必ず指定しなければならない場面があります。
それは一つのモデルクラスで複数のフィールドにForeignKeyを使うときです。
例えば以下のようなモデルを考えてみましょう。
class Dapartment(models.Model):
name = models.CharField(max_length=255)
address = models.CharField(max_length=255)
def __str__(self):
return self.name
class User(models.Model):
username = models.CharField(max_length=100, unique=True)
department = models.ForeignKey(Department, on_delete=models.CASCADE)
previous_department = models.ForeignKey(Department, on_delete=models.CASCADE)
def __str__(self):
return self.username
Userでは2つのフィールドでForeignKeyを使っています。実はこのモデルではエラーが発生してしまいます。
なぜならこれでは逆参照ができないからです。
obj.user_setではdepartmentとprevious_departmentのどちらを指定しているのかわからないですよね。
このように2つのフィールドでForeignKeyを使った場合は次のようにrelated_nameを指定する必要があります。
class User(models.Model):
username = models.CharField(max_length=100, unique=True)
department = models.ForeignKey(Department, on_delete=models.CASCADE, related_name="UserDepartment")
previous_department = models.ForeignKey(Department, on_delete=models.CASCADE, related_name="UserPreviousDepartment")
def __str__(self):
return self.username
まとめ
本記事「【Django】ForeignKeyで指定するrelated_nameについて」はいかがでしたか。
related_nameの特徴を以下にまとめます。
- 逆参照する際にrelated_nameで指定した値で逆参照ができるようになる
- ForeignKeyのオプションの一つ
- ForeignKeyに指定しなくても良い
- 指定することで<関連先モデルのクラス_set>に代わって逆参照で使用できる
- 見た目で直感的にわかるようになる
- 一つのモデルクラスで複数のフィールドにForeignKeyを使う場合はrelated_nameを必ず指定する
上記の特徴を覚えて、related_nameを使ってみてください。