. As the name implies, this filter finds results that match one of the given values, ignoring case. In other words, this is a hybrid of
.
It surprises me that there are filters for
qs.filter(field__iexact='text'),
qs.filter(field__icontains='text'), and
qs.filter(field__in=['text']), yet there is no
qs.filter(field__iin=['text']) filter.
I've made a POC for this field in postgres and it seems quite straightforward. I'd be happy to try porting into the Django codebase, but first I wanted to see if there is interest and/or feedback! Please let me know what you think.
from django.db.models import Field
from django.db.models.lookups import In
@Field.register_lookup
class IIn(In):
"""
Case-insensitive version of `__in` filters. Adapted from `In` and `IExact` transformers.
"""
lookup_name = 'iin'
def process_lhs(self, *args, **kwargs):
sql, params = super().process_lhs(*args, **kwargs)
sql = f'LOWER({sql})'
return sql, params
def process_rhs(self, qn, connection):
rhs, params = super().process_rhs(qn, connection)
params = tuple(p.lower() for p in params)
return rhs, params