【问题标题】:Performing a right join in django在 django 中执行右连接
【发布时间】:2015-02-15 02:11:51
【问题描述】:

这是我的模型

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 和出勤率的查询集,如果学生存在,否则为空?

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

【问题讨论】:

  • 你是说获取所有有出勤记录的学生吗?
  • 不,获取所有学生。如果存在,则获取学生的出勤率,否则为 null。
  • 好吧,那么这是一个简单的Student.objects.select_related('attendance') - 除非我错过了什么

标签: django orm right-join


【解决方案1】:

你可以使用这样的查询:

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

select_relatedJOIN'ing Attendance 表。 Django 没有显式的join ORM 方法,但是当您调用select_related 时,它在内部有JOIN。生成的查询集将包含所有 Student 的参加人数,并且当您对每个学生调用 attencande_set.all() 时 - 不会执行其他查询。 检查the docs for _set feature

如果您只想查询至少有一次出勤的学生,您可以使用这样的查询:

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

【讨论】:

  • 当心这不起作用 - 您不能在相关经理 (attendance_set) 上 select_related 并且对于 Count,字段名称实际上将是 attendance。您需要改用prefetch_relatedStudent.objects.all().prefetch_related('attendance_set').annotate(n_attendances=Count('attendance')).filter(n_attendances__gt=0)
【解决方案2】:

更改表主题的左连接

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

【讨论】:

    猜你喜欢
    • 2017-12-05
    • 2019-08-05
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多