【问题标题】:Django filter __contains=queryset?Django 过滤器 __contains=queryset?
【发布时间】:2013-09-08 11:15:49
【问题描述】:

我在 Ubuntu 13.04 上使用带有 Python 2.7 的 Django 1.4.3。我遇到了问题,似乎找不到解决方案。

我有一系列相关的模型(通过FK),我需要以复杂的方式过滤它们。

假设我有一个模型Car,它有Parts。我可以得到所有的零件car.parts_set。每个部分都有一个M2M字段excluded_pricePrice,还有related_name='excluded_prices'

如果我创建一个新零件,我需要将价格添加到零件的excluded_price,其中每个价格都有与该汽车相关的所有其他零件的excluded_parts。我正在尝试创建一个过滤器来帮助我找到这些价格。

基本上我想要这样的东西:

parts_set = [part for part in car.parts_set.exclude(pk=new_part.pk)]
Price.objects.filter(excluded_parts__contains=parts_set)

实际上,我想找到excluded_parts 是特定汽车零件超集的所有价格(显然不包括新零件)。

如果“parts_set”是一系列字符串,我已经找到了一种很好的方法。

parts_set = [Q(excluded_parts__contains=part) for part in car.parts_set.exclude(pk=new_part.pk)]
Price.objects.filter(reduce(operator.and_, parts_set))

很遗憾,__contains 仅适用于 SQL 语句为 LIKE 的字符串。

Django 的 ORM 中是否有任何功能支持 __contains 类型过滤器,该过滤器将值视为对象而不是字符串?

【问题讨论】:

  • 你的意思是像__in运营商吗?
  • 不,excluded_parts 是一个超级集合,所以我希望 parts_set__in excluded_parts,反之亦然。

标签: python django orm filter


【解决方案1】:

如果我正确地回答了你的问题,你可以通过迭代地在查询集上建立约束来做到这一点:

parts_set = car.parts_set.exclude(pk=new_part.pk)
price_qs = Price.objects.all()
for part in parts_set:
    price_qs = price_qs.filter(excluded_parts=part)

这将要求最终查询集中的价格在其excluded_parts 字段中包含来自parts_set 结果的所有部分。他们也可以有其他部分。 price_qs 最终应该会返回您想要的结果:

excluded_pa​​rts 是特定汽车零件的超集的所有价格

我不知道有更好的方法来构造一个要求多对多字段必须包含多个特定值的查询。

【讨论】:

  • 哇,这完全可行,我不明白他们为什么选择这种语法。 excluded_parts=part 让我大吃一惊。这是一个 M2M ......那里的平等毫无意义!不过谢谢。 :)
  • M2M 上的相等意味着“这个值必须在 M2M 中”。对于某些常见情况,例如“当前用户是否在给定的安全组中?”,这非常好。据推测,它至少部分类似于 FK。当您将过滤器链接在一起时,它们都必须为真,因此最终会说“所有 price_qs 都必须在 M2M 中”。
猜你喜欢
  • 2014-07-13
  • 2014-07-25
  • 2018-10-09
  • 2011-03-04
  • 2021-06-16
  • 2016-07-21
  • 2021-05-13
  • 2020-12-24
  • 2018-01-05
相关资源
最近更新 更多