2
0

More than 1 year has passed since last update.

[python] Django 外部キー(Parent)のデータ、filterを用いてChildのデータを参照する

Posted at

環境

Django 3.1.13
python 3.9

Code

Model

models.py
from django.db import models
from django.contrib.auth.models import User

class Work(models.Model):
    title = models.CharField('Work title', max_length=255)
    created_by = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)
    created_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title



class Commission(models.Model):
    title = models.CharField('commission title', max_length=255)
    created_at = models.DateTimeField(auto_now_add=True)
    created_by = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)
    parent_work = models.ForeignKey(Work, blank=True, null=True, on_delete=models.SET_NULL)

    def __str__(self):
        return self.title

このようにCommission(依頼)がWork(仕事)を親として持つModelを考える。

1つのParentを持つ時(外部キー)のデータ参照する

views.py
def show_commission(request, commission_id):
    commission = Commission.objects.get(pk=commission_id)

    # parent_work = commission.parent_work

    return render(request, 'show_commission.html', {"commission": commission})

特にinner joinなどをしなくても外部キーのデータを参照することができる。

複数のChildを持つParentからChildのデータを参照する

views.py
def show_work(request, work_id):

    work = Work.objects.get(pk=work_id)
    child_commissions = Commission.objects.filter(parent_work__id=work.id)

    return render(request, 'show_work.html',
                  {"work": work,
                   "child_commissions": child_commissions,
                   })

filterを用いて、Commissionモデルからparent_work.idwokr.idと一致するすべてのデータを探すことができる。

応用:外部-が持つ値でFilter参照する

from django.db.models import Q

searched = "abc"
works = Work.objects.all().filter(created_by__username__contains=searched)

Workの外部ーであるcreated_by.usernamesearchedの値を含むすべてのデータを参照する

応用:Qオブジェクトによる複数条件

searched = "abc"
works = Paginator(Work.objects.all().filter(
        Q(title__contains=searched) , Q(title__contains="cba") |
        Q(created_by__username__contains=searched)
        )

Filterの条件は
( title__contains=searched and title__contains="cba" ) or created_by__username__contains=searched

,AND
|OR
として用いられる。

関連

2
0
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
2
0