djangoormright-join

Performing a right join in django


Here are my models

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)

How can I perform a right join between Student and Attendance models, so that I can get a queryset with all of the students and attendances` if exists for a student, else null?

The documentation mentions left joins but not right joins.


Solution

  • You can use such query:

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

    With select_related you JOIN'ing Attendance table. Django does not have explicit join ORM method, but it does JOIN internally when you call select_related. Resulting queryset will contain all Student's with joined attendances, and when you will call attencande_set.all() on each student - no additional queries will be performed. Check the docs for _set feature.

    If you want to query only those students who has at least one attendance, you can use such query:

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