LoginSignup
14
20

More than 3 years have passed since last update.

Djangoで複数のリレーション取得する

Last updated at Posted at 2019-01-08

こちらの記事から参照

【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の説明はドキュメントを参考に。

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()

Post_detailのオブジェクトからcompany_idが1のオブジェクトを取得します。
filter()内はで複数テーブルをまたがってJoin。
上記の例だと「Post → Company → Company内のID」って感じでjoinしてる。

参考記事

【Python】Djangoで複数のモデル間でリレーションの取得する
SQLのSELECT文を、DjangoのQuerySet APIで書いてみた

14
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
20