我正在开发我的应用中的过滤功能。我通过jquery将逗号分隔的字符串发送到Django(在jquery中我用+替换空格,以便可以通过线路发送)。
/?ajax&sales_item=t2,+t1
现在在视图中,当我检索GET参数时,我可以看到Django已经用空格替换了+,这很棒。然后我用逗号分割关键字并删除空格。
sales_item_raw = request.GET['sales_item']
sales_item_keywords = sales_item_raw.split(',')
我首先需要检查给定的名称是否作为销售项目存在。我必须使用icontains
,因此sales_items
可以是多个项目。
for item in sales_item_keywords:
sales_items = profile.company.salesitem_set.filter(item_description__icontains=item.strip())
最后但并非最不重要的是,查询集用于过滤给定sales_items的交易:
deals_queryset = deals_queryset.filter(sales_item__in=sales_items)
如果用户仅过滤一个可以正常工作的关键字,但是如果有两个关键字,则sales_items
在每次循环迭代中都会被明显覆盖。
解决此问题的最佳方式是什么?我应该在每次迭代中将sales_items
的内容附加到循环外的列表中吗?并最终将新列表发送到最终deals_queryset.filter
?
我不确定这是否是解决此问题的好方法......
答案 0 :(得分:0)
使用Django的Q对象在过滤器中创建“或”逻辑。
# create a chain of Qs, one for each item, and "or" them together
q_filters = Q(item_description__icontains=sales_item_keywords[0].strip())
for item in sales_item_keywords[1:]:
q_filters = q_filters | Q(item_description__icontains=item.strip())
# do a single filter with the chained Qs
profile.company.salesitem_set.filter(q_filters)
这是丑陋的代码,因为我不确定如何优雅地处理初始Q,因为我不确定什么是“空”Q可以链接所有其他Q,包括第一个。 (我猜你可以使用Q(pk=pk)
,但这种方式很丑陋。)
编辑:上面的Ignacio链接显示了方式,即
q_filters = reduce(operator.or_, (Q(item_description__icontains=item.strip()) for item in sales_items_keywords))
profile.company.salesitem_set.filter(q_filters)