システムを開発していると複数モデルを作成します。ひとつの投稿に対して、さまざまな情報を紐付けることが可能です。今回はDjango(ジャンゴ)で複数モデル間でリレーションを取得して関連する値を取得する方法をご紹介します。
まずはモデル
項目はざっくりイメージ。class Company(models.Model):
name = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Post(models.Model):
name = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
company = models.ForeignKey(Company, verbose_name='投稿', on_delete=models.CASCADE)
class Post_detail(models.Model):
body = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
post = models.ForeignKey(Post, verbose_name='投稿詳細', on_delete=models.CASCADE)
(1)Company <-> (多)Post(1) <-> (多)Post_detail
mysql> show columns from company;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| created_at | datetime(6) | NO | | NULL | |
| updated_at | datetime(6) | NO | | NULL | |
+------------+--------------+------+-----+---------+----------------+
mysql> show columns from post;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| created_at | datetime(6) | NO | | NULL | |
| updated_at | datetime(6) | NO | | NULL | |
| company_id | int(11) | NO | MUL | NULL | |
+------------+--------------+------+-----+---------+----------------+
mysql> show columns from post_detail;
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| created_at | datetime(6) | NO | | NULL | |
| updated_at | datetime(6) | NO | | NULL | |
| post_id | int(11) | NO | MUL | NULL | |
+------------+-------------+------+-----+---------+----------------+
CompanyのPostを取得
# view.pyに記述
from .models import Company, Post, Post_detail
post = Post.objects.filter(company_id__exact=1).all()
company_idの後にField lookupsを指定する。exactは一致するって意味みたい。
Field lookupsの説明はドキュメントを参考に。 QuerySet API reference
Companyからpost_detailを取得する
# view.pyに記述
from .models import Company, Post, Post_detail
post_detail = Post_detail.objects.filter(post__company__id=1).all()
filter()内は 「table_name」「table_name」「column_name」で複数テーブルをまたがってJoin。
上記の例だと「Post → Company → Company内のID」って感じでjoinしてる。