Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Django's 'exact' field lookup perform a case-insensitive search?

Tags:

django

From what I read on the Django manual, I thought that the exact field lookup would perform a case-SENSITIVE search, yet, when I do this

FormZBaseElementExtraLabel.objects.filter(label__exact='his6')

I get the following output

<QuerySet [<FormZBaseElementExtraLabel: HIS6>]>

clearly not case-sensitive, and in fact identical to the default filter or iexact.

Any ideas as to what could be the problem?

Thank you

like image 378
Nicola Zilio Avatar asked Sep 20 '25 07:09

Nicola Zilio


2 Answers

Thanks to all for the answers. Indeed, I've realized that I use MySQL (MariaDB) with collation utf8mb4_unicode_ci, which explains why the exact query lookup works case-insensitively.

Without changing the collation of the underlying database (or some of its columns specifically), as pointed out, the following search is case-sensitive FormZBaseElementExtraLabel.objects.filter(label__contains = 'his6').filter(label = 'his6'). Alternatively, one could run a custom query using the raw method as explained here.

like image 129
Nicola Zilio Avatar answered Sep 23 '25 15:09

Nicola Zilio


I made this one which utilizes BINARY expr for MySQL string case-sensitive match:

from django.db.models.fields import Field
from django.db.models import Lookup

@Field.register_lookup
class StrExact(Lookup):
    """
    MySQL string case sensitive string lookup
    """

    lookup_name = 'str_exact'

    def as_sql(self, compiler, connection):
        lhs, lhs_params = self.process_lhs(compiler, connection)
        rhs, rhs_params = self.process_rhs(compiler, connection)
        params = lhs_params + rhs_params
        return "%s = binary %s" % (lhs, rhs), params

Usage:

FormZBaseElementExtraLabel.objects.filter(label__str_exact='his6').count()

Read more about Custom Lookup https://docs.djangoproject.com/en/3.0/howto/custom-lookups/

like image 24
trungnnh Avatar answered Sep 23 '25 15:09

trungnnh