#こちらの記事から参照
【Python】Djangoで複数のモデル間でリレーションの取得する
まずはモデル
項目はざっくりイメージ。
model.py
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()
Postのオブジェクトからcompany_idが1のオブジェクトを取得します。
company_idの後にField lookupsを指定する。exactは一致するって意味みたい。
Field lookupsの説明はドキュメントを参考に。
Companyからpost_detailを取得する
view.py
from .models import Company, Post, Post_detail
post_detail = Post_detail.objects.filter(post__company__id=1).all()
Post_detailのオブジェクトからcompany_idが1のオブジェクトを取得します。
filter()内は____で複数テーブルをまたがってJoin。
上記の例だと「Post → Company → Company内のID」って感じでjoinしてる。
参考記事
【Python】Djangoで複数のモデル間でリレーションの取得する
SQLのSELECT文を、DjangoのQuerySet APIで書いてみた