Skip to content

Instantly share code, notes, and snippets.

@mariocesar
Created August 9, 2024 19:09
Show Gist options
  • Save mariocesar/5a07aaf0c8a726149a0185505ac43322 to your computer and use it in GitHub Desktop.
Save mariocesar/5a07aaf0c8a726149a0185505ac43322 to your computer and use it in GitHub Desktop.
SearchableCharField in Django, GIN Index for case-insensitive search
from django.db import models
from django.contrib.postgres.indexes import GinIndex
from django.db.models.functions import Lower
class SearchableCharField(models.CharField):
def contribute_to_class(self, cls, name, **kwargs):
super().contribute_to_class(cls, name, **kwargs)
# Add a GIN index with trigram operations for fast search
cls._meta.indexes.extend([
GinIndex(fields=[name], opclasses=["gin_trgm_ops"]),
# For case-insensitive search
GinIndex(fields=[Lower(name)], name=f"{name}_lower_trgm_idx", opclasses=["gin_trgm_ops"]),
])
# Use like this
class Author(models.Model):
full_name = SearchableCharField(max_length=100)
# Use in a query with __icontains
Author.objects.filter(full_name__icontains="Pedro")
# SELECT * FROM author WHERE full_name ILIKE '%Pedro%';
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment