我正在动态构建一些Django过滤器查询using this example:
kwargs = { 'deleted_datetime__isnull': True }
args = ( Q( title__icontains = 'Foo' ) | Q( title__icontains = 'Bar' ) )
entries = Entry.objects.filter( *args, **kwargs )
我只是不确定如何构建args
的条目。说我有这个数组:
strings = ['Foo', 'Bar']
我如何从那里到:
args = ( Q( title__icontains = 'Foo' ) | Q( title__icontains = 'Bar' )
我能得到的最接近的是:
for s in strings:
q_construct = Q( title__icontains = %s) % s
args.append(s)
但我不知道如何设置|
条件。
答案 0 :(得分:13)
你有Q类对象的列表,
args_list = [Q1,Q2,Q3] # Q1 = Q(title__icontains='Foo') or Q1 = Q(**{'title':'value'})
args = Q() #defining args as empty Q class object to handle empty args_list
for each_args in args_list :
args = args | each_args
query_set= query_set.filter(*(args,) ) # will excute, query_set.filter(Q1 | Q2 | Q3)
# comma , in last after args is mandatory to pass as args here
答案 1 :(得分:12)
您可以使用kwarg格式直接迭代它(我不知道正确的术语)
argument_list = [] #keep this blank, just decalring it for later
fields = ('title') #any fields in your model you'd like to search against
query_string = 'Foo Bar' #search terms, you'll probably populate this from some source
for query in query_string.split(' '): #breaks query_string into 'Foo' and 'Bar'
for field in fields:
argument_list.append( Q(**{field+'__icontains':query_object} ) )
query = Entry.objects.filter( reduce(operator.or_, argument_list) )
# --UPDATE-- here's an args example for completeness
order = ['publish_date','title'] #create a list, possibly from GET or POST data
ordered_query = query.order_by(*orders()) # Yay, you're ordered now!
这将在query_string
中的每个字段fields
中查找每个字符串,并在结果中查找
我希望我仍然拥有我的原始资源,但这是根据我使用的代码改编的。
答案 2 :(得分:0)
firstQ = [
Q(...),
Q(...),
Q(...)
]
import functools
functools.reduce(lambda a, b: a & b, Qrelationship)
或者就我而言,我需要对不同的过滤器集进行“与”操作:
firstQ = [
Q(...),
Q(...),
Q(...)
]
secondQ = [
Q(...),
Q(...),
Q(...)
]
import functools
combined = functools.reduce(lambda a, b: a | b, [
functools.reduce(lambda a, b: a & b, firstQ),
functools.reduce(lambda a, b: a & b, secondQ)
])
myqueryset = Model.objects.filter(combined)
# Make sure you apply the Q's first (BEFORE any other filter) or it will fail silently