[Django]-How can I chain Django's "in" and "iexact" queryset field lookups?

38👍

Here’s my solution, which uses Q objects instead:

name_list = ['Alpha', 'bEtA', 'omegA']
q_list = map(lambda n: Q(name__iexact=n), name_list)
q_list = reduce(lambda a, b: a | b, q_list)
MyModel.objects.filter(q_list)

5👍

name_list = ['Alpha', 'bEtA', 'omegA']
results = MyModel.objects.none()
for name in name_list:
    results |= MyModel.objects.filter(name__iexact=name)

Ok I test it and it works 🙂

2👍

How about annotating the target record with the transformed name as lower case? Should reduce the number of conditions required considerably, boosting performance…

from django.db.models.functions import Lower

lcase_name_list = [x.lower() for x in name_list]
MyModel.objects.annotate(lcase_name=Lower('name').filter(lcase_name__in=lcase_name_list)

1👍

Here is an example using a list comprehension. It is similar to catherine’s answer, but with one database hit like Derek Kwok’s answer (but procedural instead of functional).

q_list = Q()
for q in [Q(name__iexact=n) for n in name_list]:
    q_list |= q
MyModel.objects.filter(q_list)

For those that like to avoid zip, map, reduce, and such in Python.

👤Kevin

Leave a comment