Filter with arbitrary number or Q objects combined by OR logical operator

微笑、不失礼 提交于 2019-12-25 07:24:02

问题


Django 1.10.1

Search form. The user inserts words separated by spaces. Necessary to find objects with ANY of these words in the title field.

I'm planning to use something like this:

Article.objects.filter(
    Q(title__icontains="table") | Q(title__icontains="helm")
)

I can make Q objects easily: q = Q(title__icontains="table").

But the obstacle is how to pass arguments to the filter method.

https://docs.djangoproject.com/en/1.10/topics/db/queries/

The syntax is filter(**kwargs).

With a loop I can prepare a dictionary like this :

q_objects = {"1": Q(title__icontains="table"), "2": Q(title__icontains="glasses")}

But the problem is with that "|".
How to pass it to the filter method is a mystery to me. In other words I fail to build a filter with OR logical operator.

Could you help me?


回答1:


You can do something like this:

queryset = MyModel.objects.all()
queries = ['table, helm']
filter_ = 'title__icontains'

queryset.filter(reduce(lambda q1,q2: q1|q2, [Q(**{filter_: q}) for q in queries], Q()))

#This will build a QuerySet similar to this one:
queryset.filter(Q(title__icontains='table')|Q(title__icontains='helm')) 



回答2:


query = Q()
for word in words:
    query |= Q(title__icontains=word)
Article.objects.filter(query)

or

from operator import __or__ as OR
from functools import reduce

query = [Q(title__icontains=word) for word in words]
Article.objects.filter(reduce(OR, query))



回答3:


In the same line as proposed by @Todor and based on this post, I like this syntax better:

reduce(operator.or_, (Q(title__icontains=x) for x in ['x', 'y', 'z']))

The full code with your example could be:

list_of_words = ['table', 'helm']   # words wanted by the user

Article.objects.filter(
     reduce(operator.or_, (Q(title__icontains=word) for word in list_of_words))
)


来源:https://stackoverflow.com/questions/39829064/filter-with-arbitrary-number-or-q-objects-combined-by-or-logical-operator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!