1. ホーム
  2. python

[解決済み] LEFT JOIN Django ORM

2022-02-19 15:19:30

質問

以下の機種を持っています。

class Volunteer(models.Model):
    first_name = models.CharField(max_length=50L)
    last_name = models.CharField(max_length=50L)    
    email = models.CharField(max_length=50L)
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES)


class Department(models.Model):
    name = models.CharField(max_length=50L, unique=True)
    overseer = models.ForeignKey(Volunteer, blank=True, null=True)
    location = models.CharField(max_length=100L, null=True)


class DepartmentVolunteer(models.Model):
    volunteer = models.ForeignKey(Volunteer)
    department = models.ForeignKey(Department)
    assistant = models.BooleanField(default=False)
    keyman = models.BooleanField(default=False)
    captain = models.BooleanField(default=False)
    location = models.CharField(max_length=100L, blank=True, null=True)

私は、ボランティアが割り当てられていないすべての部門をクエリしたいのです。次のクエリを使用して、これを行うことができます。

SELECT 
    d.name 
FROM   
    vsp_department AS d
LEFT JOIN vsp_departmentvolunteer AS dv
ON d.id = dv.department_id  
WHERE
    dv.department_id IS NULL;

もっとdjangoらしいやり方はないのでしょうか、それとも生のsqlで行くべきなのでしょうか?

どのように解決するのですか?

ルックアップで後方関係をたどればできる。

>>> qs = Department.objects.filter(departmentvolunteer__isnull=True).values_list('name', flat=True)
>>> print(qs.query)
SELECT "app_department"."name" FROM "app_department" LEFT OUTER JOIN
"app_departmentvolunteer" ON ( "app_department"."id" = "app_departmentvolunteer"."department_id" )
WHERE "app_epartmentvolunteer"."id" IS NULL

以下は、クエリー "複数値の関係をスパンする"に関するドキュメントです。 https://docs.djangoproject.com/en/stable/topics/db/queries/#spanning-multi-valued-relationships