2016-10-03 36 views
0

的Django 1.10.1濾波器具有任意數目或Q對象通過合併OR邏輯運算

搜索表單。用戶插入由空格分隔的單詞。 必須在標題字段中找到這些詞的ANY的對象。

我打算用這樣的:

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

我可以讓Q對象容易:Q = Q(title__icontains = 「表」)。

但障礙是如何將參數傳遞給過濾器方法。

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

的語法是濾波器(** kwargs)

有了一個循環我可以編寫這樣一本字典:

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

但問題是與「|」
如何將它傳遞給過濾器方法對我來說是個謎。換句話說,我無法用OR邏輯運算符構建過濾器。

你能幫我嗎?

回答

0

你可以做這樣的事情:

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')) 
+0

親愛的Todor,謝謝你的回答。看起來很有希望。我必須消化。如果這有效,我會很樂意接受。 – Michael

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

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)) 
0

在同一行提出@Todor,總部設在this post,我喜歡這種語法更好:

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

你的例子中的完整代碼可能是:

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