Django 1.10.1
搜索表单。用户插入由空格分隔的单词。 必须在标题字段中找到具有 ANY 这些单词的对象。
我打算用这样的东西:
Article.objects.filter(
Q(title__icontains="table") | Q(title__icontains="helm")
)
我可以轻松制作Q对象:q = Q(title__icontains =“table”)。
但障碍是如何将参数传递给过滤器方法。
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 :(得分:2)
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))
答案 1 :(得分:1)
您可以这样做:
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 :(得分:1)
在@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))
)