The new TrigramSimilarity feature of the django.contrib.postgres was great for a problem I had. I use it for a search bar to find hard to spell latin names. The problem is that
To make Django 2.2 use the index for icontains
and similar searches:
Subclass GinIndex to make an case insensitive index (uppercasing all field values):
from django.contrib.postgres.indexes import GinIndex
class UpperGinIndex(GinIndex):
def create_sql(self, model, schema_editor, using=''):
statement = super().create_sql(model, schema_editor, using=using)
quote_name = statement.parts['columns'].quote_name
def upper_quoted(column):
return f'UPPER({quote_name(column)})'
statement.parts['columns'].quote_name = upper_quoted
return statement
Add the index to your model like this, including kwarg name
which is required when using opclasses
:
class MyModel(Model):
name = TextField(...)
class Meta:
indexes = [
UpperGinIndex(fields=['name'], name='mymodel_name_gintrgm', opclasses=['gin_trgm_ops'])
]
Generate the migration and edit the generated file:
# Generated by Django 2.2.3 on 2019-07-15 10:46
from django.contrib.postgres.operations import TrigramExtension # <<< add this
from django.db import migrations
import myapp.models
class Migration(migrations.Migration):
operations = [
TrigramExtension(), # <<< add this
migrations.AddIndex(
model_name='mymodel',
index=myapp.models.UpperGinIndex(fields=['name'], name='mymodel_name_gintrgm', opclasses=['gin_trgm_ops']),
),
]