Oms
Oms

Reputation: 203

How to mix AND and OR operators in Django query?

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

Answers (1)

alecxe
alecxe

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:

  • use __in instead of several ORs
  • collect these in queries for each search field and then join them with AND

Hope that helps.

Upvotes: 1

Related Questions