具有从另一个查询集过滤的值的Queryset

时间:2018-01-28 23:04:50

标签: python django django-queryset

如果我有这样的查询集qs1:

<QuerySet [{u'name': u'John', u'birthdate': u'1980-01-01'}, 
           {u'name': u'Larry', u'birthdate': u'1976-12-28'}, 
            .....']}

我需要使用与key&#39; name&#39;相关联的所有值。从qs1查询另一个模型并得到qs2像这样:

<QuerySet [{u'student_name': u'John', u'grade': u'A'}, 
           {u'student_name': u'Larry', u'grade': u'B'}, 
            .....']}

在此之后,我必须结合qs1和qs2,所以final_qs是这样的:

[{u'name': u'John',u'birthdate': u'1980-01-01', u'grade': u'A'}, 
 {u'student_name': u'Larry', u'birthdate': u'1976-12-28', u'grade': u'B'}, 
  .....']}

我将如何实现这一目标? 我有这样的代码:

qs1 = Person.objects.values('name', 'birthdate')
for t in qs1:
     qs2 = Grades.objects.filter(student_name=t['name'])
                               .values('student_name', 'grade')

我的qs1看起来不错。但是,我的qs2变成了这个:

<QuerySet [{u'student_name': u'John', u'grade': u'A'}]>
<QuerySet [{u'student_name': u'Larry', u'grade': u'B'}]>

由于qs2,我无法使用zip(qs1,qs2)按照我想要的方式构建final_qs。

2 个答案:

答案 0 :(得分:1)

我会将所有qs1个名称汇总到一个列表中:

names = [t['name'] for t in qs1]

然后执行以下查询:

qs2 = Grades.objects.filter(student_name__in=names)
                           .values('student_name', 'grade')

后者只会从student_name中选择namesqs1所在的行,并且应返回包含所有匹配行的QuerySet行。

答案 1 :(得分:0)

我假设您的成绩模型包含ForeignKey(Person),这意味着创建了反向关系。这意味着你可以"follow the relationship backwards"和各种其他django魔法。

因此,如果您有qs1的查询集Person

>>> qs1.values('student_name', 'birthdate', 'grade_set__grade')

这种神秘的'grade_set__grade'可以观察到上述魔法。

Django实际上已向您添加了另一个字段Person模型:.grade_set。这将是属于该人员实例的所有等级。然后我们可以通过我们在过滤器中使用的djangos双下划线表示法访问所有这些等级。

您可以通过User.objects.last().grade_set

快速尝试

<强>加成

不喜欢“grade_set”这个词,还喜欢别的什么?您可以在成绩模型中更改此设置。

   class Grade(models.Model):
       # some fields
       ForeignKey(Person, related_name='all_their_grades')
       # other fields

您现在可以User.objects.last().all_their_grades执行与以前相同的操作。请注意,更改后,.grade_set将不再可用。