M2M场上的Django滤波与循环

2024-05-20 10:26:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个的id列表,我需要在Django中查询和过滤(使用and)。我想使用一些类似于下面例子2的东西,但是它给出了不正确的结果0。型号很简单,很多产品可以有很多标签。例2有什么问题?你知道吗

正确的结果

例1:

  q = Product.objects.all()
                for id in _list_of_ids:
                    q.filter(tags__id=id)

例2:

结果不正确,但似乎更好(edited for brevity)。。。你知道吗

for id in _list_of_ids:
     q = Q(tags__id=id)
     # apend q here etc

# q = (AND: ('tags__id', 1), ('tags__id', 2))
Products.objects.filter(q)

Tags: andofdjangoinidids列表for
3条回答
q = Product.objects.filter(tags__id__in=list_of_ids) 

您要搜索的是:

products = reduce(lambda qs, p_id: qs.filter(tags=p_id), _list_of_ids, Product.objects.all())

基本上,一个带有多个Q对象的.filter调用和多个带有单个Q对象的.filter调用之间是有区别的。你知道吗

在第一个场景中,您将得到一个内部联接,其中应用了所有Q过滤器。你知道吗

在第二个场景中,您得到许多内部连接,每个连接只应用一个Q对象。你知道吗

在您的例子中,当您搜索一个产品时,有多个标记的组合,您需要为每个标记创建一个内部连接,以便找到这样的产品(这是第二种情况),因此您需要许多.filter调用。你知道吗

更多信息请参见文档:Spanning multi-valued relationships

例2的完整代码是什么?你知道吗

像这样的事情似乎应该管用。。。你知道吗

q_expression = [Q("tags__", id) for id in list_of_ids]
queryset = Product.objects.filter(reduce(operator.and_, q_expression))

相关问题 更多 >