【问题标题】:Django Filtering Specific QuerySet.values()Django 过滤特定的 QuerySet.values()
【发布时间】:2014-09-07 08:31:50
【问题描述】:

假设我有一个模型类Parent 和一个类Child。并且 child 有一个名为 status 的字段以及与 ParentForeignKey 关系。

假设我通过调用 p = Parent.objects.filter(pk=1) 来调用过滤器(以便拥有一个 QuerySet)来检索一个父级

现在,如果我打电话给p.values('children__name'),我将收到一份包含该父母的孩子姓名的词典列表。

我的问题是,如果我想调用 p.values('children__name') 但仅在孩子的 status 是特定的时才限制值,我该怎么做?

我还想确保原始 QuerySet 保持不变,因为我不想过滤掉它(对于更大的 QuerySet)。我只想过滤基于某些参数的值。

在 Django 中有没有办法做到这一点?

【问题讨论】:

    标签: python django django-queryset


    【解决方案1】:

    您只需过滤:

    p.filter(children__status='whatever').values('children__name')
    

    【讨论】:

    • 我不想改变原来的 QuerySet(这样做)。因此,例如,如果我想列出所有状态为“生病”的父母和孩子,那么我不能只做你所做的,因为它会将父母过滤掉。我希望仍然保留所有父母,只需将“children__name”的值过滤到具有特定状态的人。这有意义吗?
    • 这会获取拥有任何状态为“whatever”的孩子的父母,然后获取这些父母的所有孩子姓名。如果他们有一个状态为“随便”的“兄弟姐妹”,那么这也会让你成为其他状态的孩子
    • 对我来说很好
    【解决方案2】:

    您可以使用 Prefetch 过滤 M2M 关系上的子值。 Prefetch 指定如何从 Parent 和 Child 之间的直通表中获取数据,prefetch_related 会触发实际查询。

    from django.db.models import Prefetch
    
    pf = Prefetch('children', Child.objects.filter(status='SICK')
    parents = Parent.objects.filter(pk=1).prefetch_related(pf)
    
    sick_children_names = []
    for parent in parents:
        sick_children_names.append([child.name for child in parent.children.all()])
    

    另一种方法是使用直通表本身。

    names = Parent.children.through.objects.filter(parent_id=1, child__status='SICK').values('children__name')
    

    或者使用现有的 qs p:

    names = Parent.children.through.objects.filter(parent_id__in=p, child_status='SICK').values('children__name')
    

    更多关于 M2M 通过here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-25
      • 2017-02-22
      • 2014-11-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-10
      • 2020-12-16
      • 2021-07-13
      相关资源
      最近更新 更多