Encontré un artículo del 12/2020 que usa la versión más nueva de Django ORM como tal:
class Author(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
class Meta:
indexes = [
GinIndex(
name='review_author_ln_gin_idx',
fields=['last_name'],
opclasses=['gin_trgm_ops'],
)
]
Si, como el póster original, estaba buscando crear un índice que funcione con icontains, tendrá que indexar la parte SUPERIOR () de la columna, lo que requiere un manejo especial de OpClass :
from django.db.models.functions import Upper
from django.contrib.postgres.indexes import GinIndex, OpClass
class Author(models.Model):
indexes = [
GinIndex(
OpClass(Upper('last_name'), name='gin_trgm_ops'),
name='review_author_ln_gin_idx',
)
]
Inspirado en un artículo antiguo
sobre este tema, llegué a un el actual
que da la siguiente solución para un GistIndex
:
Actualización:desde Django-1.11 las cosas parecen ser más simples, ya que esta respuesta y documentos de Django sugerir:
from django.contrib.postgres.indexes import GinIndex
class MyModel(models.Model):
the_field = models.CharField(max_length=512, db_index=True)
class Meta:
indexes = [GinIndex(fields=['the_field'])]
De Django-2.2 , un atributo opclasses
estará disponible en la clase class Index(fields=(), name=None, db_tablespace=None, opclasses=())
para este propósito.
from django.contrib.postgres.indexes import GistIndex
class GistIndexTrgrmOps(GistIndex):
def create_sql(self, model, schema_editor):
# - this Statement is instantiated by the _create_index_sql()
# method of django.db.backends.base.schema.BaseDatabaseSchemaEditor.
# using sql_create_index template from
# django.db.backends.postgresql.schema.DatabaseSchemaEditor
# - the template has original value:
# "CREATE INDEX %(name)s ON %(table)s%(using)s (%(columns)s)%(extra)s"
statement = super().create_sql(model, schema_editor)
# - however, we want to use a GIST index to accelerate trigram
# matching, so we want to add the gist_trgm_ops index operator
# class
# - so we replace the template with:
# "CREATE INDEX %(name)s ON %(table)s%(using)s (%(columns)s gist_trgrm_ops)%(extra)s"
statement.template =\
"CREATE INDEX %(name)s ON %(table)s%(using)s (%(columns)s gist_trgm_ops)%(extra)s"
return statement
Que luego puede usar en su clase modelo como esta:
class YourModel(models.Model):
some_field = models.TextField(...)
class Meta:
indexes = [
GistIndexTrgrmOps(fields=['some_field'])
]