Reputation: 203
I a Django beginner, I figured out how to dynamically create a model query but I'm stuck at some point when I'm tring to mix AND
and OR
operators:
I have a list of fields (contact_name, company, position, country), these fields might contain more than one keyword (separated by comma ',')
So if I search for these company names "imtech, ABC, FooBar" I get the right result with the code I have below, because it always uses the |
(OR) operator.
But what if I want to restrict the search for entries with company field as "imtech, ABC, FooBar" AND position field as "Account Manager" only?
I know I have to put the &
operator at the end of each loop of fields but I haven't succeded doing so, so here is my code, please help me!!!
search_fields = {'contact_name', 'company', 'position', 'country'}
search_fields_values = {}
qs_params = None
for field in search_fields:
search_fields_values[field] = self.request.GET.get(field, None)
if search_fields_values[field]:
search_fields_values[field] = search_fields_values[field].split(',')
for part in search_fields_values[field]:
q = Q(**{field: part})
qs_params = qs_params | q if qs_params else q
qs = qs.filter(qs_params)
Thanks a million!
Upvotes: 1
Views: 1124
Reputation: 473863
I hope I understood your question correctly.
Here's what should work in theory (haven't tested it though):
import operator
...
search_fields = {'contact_name', 'company', 'position', 'country'}
conditions = []
for name in search_fields:
value = self.request.GET.get(name, None)
if value:
conditions.append(Q(**{name + "__in": value.split(',')}))
qs = qs.filter(reduce(operator.and_, conditions))
So, two ideas came into my mind:
__in
instead of several ORs in
queries for each search field and then join them with ANDHope that helps.
Upvotes: 1