2014-12-16 2 views
3

Вот мои моделиВыполнение право участвовать в Джанго

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) 

Как я могу выполнить право вступать между Student и Attendance моделей, так что я могу получить QuerySet со всеми students и attendances` если существует для ученика, иначе null?

В документации упоминаются левые соединения, но не правильные соединения.

+0

ли вы сказать выборки всех студентов, которые рекорд посещаемости? – karthikr

+0

нет, принесите всех учеников. выберите посещаемость для учащегося, если он существует, иначе null. – rjv

+0

ну, тогда это просто 'Student.objects.select_related ('attendance')' - если я не пропущу что-то – karthikr

ответ

1

Вы можете использовать такой запрос:

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 таблицы. Django не имеет явного метода join ORM, но он вызывает JOIN внутри, когда вы звоните select_related. Результирующий запрос будет содержать все 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)) 
+3

Остерегайтесь, так как это не сработает - вы не можете выбрать_related на связанного менеджера ('attendance_set'), и имя поля фактически будет 'посещением' для' Count'. Вместо этого вы должны использовать 'prefetch_related':' '' Student.objects.all(). Prefetch_related ('attendance_set'). Annotate (n_attendances = Count ('attendance')). Filter (n_attendances__gt = 0) '' ' – Ben

Смежные вопросы