如何从request.GET参数创建过滤器?

时间:2012-08-31 12:19:39

标签: django

  

可能重复:
  filter using Q object with dynamic from user?

我正在开发我的应用中的过滤功能。我通过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

我不确定这是否是解决此问题的好方法......

1 个答案:

答案 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)