在 Django 中执行右连接

rjv*_*rjv 5 django orm right-join

这是我的模型

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)
Run Code Online (Sandbox Code Playgroud)

如何在StudentAttendance模型之间执行正确的连接,以便我可以获得包含所有students和出勤率的查询集,如果存在,则为学生,否则为空?

文档提到了左连接但没有提到右连接。

mad*_*rdi 6

更改表主题的左连接

queryset.query.alias_map['subject'].join_type = "RIGHT OUTER JOIN"
Run Code Online (Sandbox Code Playgroud)


Gil*_*tes 4

您可以使用这样的查询:

queryset = Student.objects.all().select_related('attendance_set')
student = queryset[0]
# all attendances for the student
attendances = student.attendance_set.all() 
Run Code Online (Sandbox Code Playgroud)

select_relatedJOIN同桌Attendance。Django 没有显式的joinORM 方法,但当JOIN您调用select_related. 生成的查询集将包含所有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))
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这不起作用 - 您无法在相关管理器(“attendance_set”)上选择_相关,并且字段名称实际上是“Count”的“attendance”。您需要使用`prefetch_lated`代替:```Student.objects.all().prefetch_lated('attendance_set').annotate(n_attendances=Count('attendance')).filter(n_attendances__gt=0)``` (10认同)