Построение динамических запросов Django динамически с помощью args и kwargs

Я создаю динамические запросы Django динамически, используя этот пример:

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)

Но я не знаю, как настроить условие |.

Ответ 1

Вы можете перебирать его напрямую, используя формат 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 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 и OR результат

Мне жаль, что у меня все еще не было оригинального источника, но это адаптировано из кода, который я использую.

Ответ 2

у вас есть список объектов класса 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