はじめに
Djangoにてモデル同士を紐づける際に用いるmodels.ForeignKey()の引数の中でrelated_nameというパラメータがあるが、いつ使われるのかが分からなかったので調べてみた。
前提
今回は以下のように、CategoryモデルとPostモデルを作成して考える。
apps/models.py
class Category(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(unique=True)
def __str__(self):
return self.name
class Post(models.Model):
category = models.ForeignKey(to=Category, on_delete=models.CASCADE)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
content = models.TextField()
def __str__(self):
return self.title
上のコードでcategoryオブジェクトを3つ、Postオブジェクトを6つ生成し、次の図の様な関係をもつとする。
以下2つの場合分けを行いそれぞれの方法を考える。
- 二次関数(post.id=1)に紐づくcategoryを取得したい時《多→1の参照》
- 社会(category.id=3)に紐づくpostをすべて取得したい時《1→多の参照》
多 → 1 への参照方法
オブジェクト.フィールド名
で取得可能
>>> post1 = Post.object.get(id=1)
>>> post1
<Post: 二次関数>
>>> post1.category
<Category: 数学>
1 → 多 への参照方法 【 _set.all() 】
オブジェクト.モデル名(小文字)_set.all()
で取得可能
>>> category3 = Category.object.get(id=3)
>>> category3
<Category: 社会>
>>> category3.post_set.all()
<QuerySet [<Post: 坂本龍馬>, <Post: 鎌倉幕府>]>
※ .all()の他に.filter()や.count()などを使って絞り込みやオブジェクト数をカウントしたりもできる。
related_nameとは
- models.ForeignKeyの引数の一つで別になくても良い。
- related_nameを指定すると
モデル名(小文字)_set
に置き換えて使用可能となる。 - related_name=’posts’とすると先ほどの例では、
category3.post_set.all()
→→category3.posts.all()
となり、より直感的に分かるようになる。
引数としてrelated_nameを追加
apps/models.py
class Category(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(unique=True)
class Post(models.Model):
category = models.ForeignKey(to=Category, on_delete=models.CASCADE, related_name='posts') #追加
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
content = models.TextField()
related_nameを活用する
>>> category3 = Category.object.get(id=3)
>>> category3
<Category: 社会>
>>> category3.posts.all() #変更
<QuerySet [<Post: 坂本龍馬>, <Post: 鎌倉幕府>]> # ←結果は同じ