关于prefetch_related的Django ORM注释

时间:2016-12-09 10:55:43

标签: mysql django django-orm

如何在prefetch_related查询期间注释相关模型?

我有两种模式:

class Subject(models.Model):
    ...

class Student(models.Model):
    subjects = models.ManyToManyField(Subject, related_name="students")

我希望在单个查询中检索Subject个对象,与每个Student相关的Subject个对象以及每个Student的{​​{1}}个数。 我试图通过以下查询来完成它:

Subject.objects.all().prefetch_related( Prefetch("student", queryset=Student.objects.all().annotate(subjects_count=Count("subject"))) )

但是我收到了一个SQL错误:

OperationalError at /concerts/coldplay-en-madrid/ (1055, "Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'studentsubject.subject_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by")

1 个答案:

答案 0 :(得分:0)

因此,根据您的要求,您可以制作一个'通过'用于处理学科与学生之间M2M关系的表格。所以,你的模型看起来像:

class Subject(models.Model):
    ...

class Student(models.Model):
    subjects = models.ManyToManyField(to=Subject, through='StudentSubject', related_name="students")

class StudentSubject(models.Model):
    student = models.ForeignKey(to=Student, related_name='student_subjects')
    subject = models.ForeignKey(to=Subject, related_name='subject_students')

您可以从here了解有关表格的更多信息。 现在,您可以这样查询:

from django.db.models import Count
students = Student.objects.prefetch_related('student_subjects')

subjects_associated_with_students = students.annotate(num_subjects=Count('student_subjects')

subjects_associated_with_students是一个查询集,您现在可以执行任何常规操作。对于前subjects_associated_with_students.filter(num_subjects__gt=1)。这将为您提供至少有1个科目的所有学生。

希望它有所帮助。