【问题标题】:Queryset with values filtered from another queryset具有从另一个查询集中过滤的值的查询集
【发布时间】:2018-07-07 14:54:46
【问题描述】:

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

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

我需要使用 qs1 中与键 'name' 关联的所有值来查询另一个模型并获得 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。

【问题讨论】:

    标签: python django django-queryset


    【解决方案1】:

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

    所以假设你有一个查询集qs1 Persons:

    >>> 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 将不再可用。

    【讨论】:

      【解决方案2】:

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

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

      然后执行以下查询:

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

      后者只会从qs1 中选择student_namenames 中的行,并且应该返回一个包含所有匹配行的QuerySet

      【讨论】:

      • 谢谢!这对 qs2 非常有效。但是,当我这样做时:queryset = [x + y[1:] for (x, y) in zip(qs1, qs2)]。我收到“TypeError: unhashable type”。
      • 是的,因为你正在切片字典,你到底想用这个y[1:]做什么?你可以找到类似的问题here
      猜你喜欢
      • 1970-01-01
      • 2014-12-13
      • 2019-04-23
      • 1970-01-01
      • 1970-01-01
      • 2019-10-30
      • 1970-01-01
      • 2018-12-04
      • 1970-01-01
      相关资源
      最近更新 更多