prefetch_related 上的 Django ORM 注释
Posted
技术标签:
【中文标题】prefetch_related 上的 Django ORM 注释【英文标题】:Django ORM annotation on prefetch_related 【发布时间】:2017-04-24 20:05:29 【问题描述】:如何在 prefetch_related 查询期间注释相关模型?
我有两个模型:
class Subject(models.Model):
...
class Student(models.Model):
subjects = models.ManyToManyField(Subject, related_name="students")
我想在单个查询中检索 Subject
对象,与每个 Subject
相关的 Student
对象以及每个 Student
具有的数量。
我正在尝试使用以下查询来完成它:
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")
【问题讨论】:
尝试这样做:Subject.objects.annotate(subjects_count=Count('students')).prefetch_related('students') 这样我得到了每个科目有多少学生,但我想得到相反的关系:每个学生有多少科目。无论如何感谢您的帮助! 【参考方案1】:因此,根据您的要求,您可以制作一个“通过”表来处理主题和学生之间的 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 个科目的所有学生。
希望对你有帮助。
【讨论】:
我认为这不是正确的答案。我想获得Subject
对象,但使用此解决方案我将获得Students
。谢谢!以上是关于prefetch_related 上的 Django ORM 注释的主要内容,如果未能解决你的问题,请参考以下文章
django- 在另一个 prefetch_related 中使用 prefetch_related
AttributeError:“Resume”对象没有“prefetch_related”属性