47 lines
1.3 KiB
Python
47 lines
1.3 KiB
Python
from django.db.backends.signals import connection_created
|
|
from django.db.models import CharField, Transform
|
|
from django.dispatch import receiver
|
|
from rest_framework.filters import SearchFilter
|
|
|
|
SQLITE_CASEFOLD_FUNCTION = "EUSRR_CASEFOLD"
|
|
|
|
|
|
def _casefold(value):
|
|
return None if value is None else str(value).casefold()
|
|
|
|
|
|
@receiver(connection_created, dispatch_uid="commerce.sqlite_unicode_casefold")
|
|
def register_sqlite_casefold(sender, connection, **kwargs):
|
|
if connection.vendor != "sqlite":
|
|
return
|
|
connection.connection.create_function(
|
|
SQLITE_CASEFOLD_FUNCTION,
|
|
1,
|
|
_casefold,
|
|
deterministic=True,
|
|
)
|
|
|
|
|
|
class UnicodeCasefold(Transform):
|
|
lookup_name = "unicode_casefold"
|
|
function = "LOWER"
|
|
output_field = CharField()
|
|
|
|
def as_sqlite(self, compiler, connection, **extra_context):
|
|
return super().as_sql(
|
|
compiler,
|
|
connection,
|
|
function=SQLITE_CASEFOLD_FUNCTION,
|
|
**extra_context,
|
|
)
|
|
|
|
|
|
CharField.register_lookup(UnicodeCasefold)
|
|
|
|
|
|
class UnicodeCasefoldSearchFilter(SearchFilter):
|
|
"""DRF substring search with Unicode-aware case normalization."""
|
|
|
|
def get_search_terms(self, request):
|
|
return [term.casefold() for term in super().get_search_terms(request)]
|