15
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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で書いてみた

15
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
15
20

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?