在Django中执行右连接

iklwldmw  于 2023-03-24  发布在  Go
关注(0)|答案(3)|浏览(209)

这是我的模特

class Student:
    user  = ForeignKey(User)
    department = IntegerField()
    semester = IntegerField()
    ...

class Attendance:
    student = ForeignKey(Student)
    subject = ForeignKey(Subject)
    month = IntegerField()
    year = IntergerField()
    present = IntegerField() 
    total = IntegerField()

students = Student.objects.filter(semester=semester)

如何在StudentAttendance模型之间执行右连接,以便获得包含所有students和出勤率的查询集` if exists for a student,else null?
文档中提到了左连接,但没有提到右连接。

v64noz0r

v64noz0r1#

更改表主题的左连接

queryset.query.alias_map['subject'].join_type = "RIGHT OUTER JOIN"
mwecs4sa

mwecs4sa2#

您可以使用这样的查询:

queryset = Student.objects.all().select_related('attendance_set')
student = queryset[0]
# all attendances for the student
attendances = student.attendance_set.all()

使用select_related,您可以JOIN 'ing Attendance table。Django没有显式的join ORM方法,但当您调用select_related时,它会在内部执行JOIN。结果查询集将包含所有具有联合出席的Student,以及当您对每个学生调用attencande_set.all()时-将不执行其他查询。检查_set功能的文档。
如果只想查询至少有一次出勤的学生,可以这样查询:

from django.models import Count
(Student.objects.all()
                .select_related('attendance_set')
                .annotate(n_attendances=Count('attendance_set'))
                .filter(n_attendances__gt=0))
oug3syen

oug3syen3#

正确的方法是使用fk_set__isnull=false,如下所示:

class Father(Model):
    name = ...

class Child(Model):
    father = ForeignKey('Father', on_delete=..., related_name='childs')

>>> fathers_with_childs = Father.objects.filter(childs__isnull=False).all()

这会给你一个类似这样的查询:
"SELECT * FROM father INNER JOIN child ON (father.id = child.father_id) WHERE child.id IS NOT NULL"

相关问题