Django 3.2 LTS Functional indexes

Pull request Added support for functional indexes. #11929

This is enables pretty powerful expressions like having tsvector GIN-indexes on regular columns:

GinIndex(
    fields=[Cast('field', SearchVectorField())], name=index_name
)

or B-Tree indexes on keys in jsonb columns which values are not text:

Index(
    fields=[Cast(KeyTextTransform('some_key', 'field'), IntegerField())], name=index_name
)

Twitter Announces

pauloxnet

../../../_images/annonces_twitter.png

https://twitter.com/pauloxnet/status/1347977856371089408?s=20

Very Nice! Always exciting to see such features being added to the ORM

You are right. In the last project I would have needed the functional
indexes and looking in the Django code I realized that there was
already an open PR.

It is nice to be part of a community where many collaborate for growth.

Full-text search and spatial data are the Django functions I deal with most.

Think of all the functions this can support!

Adam Johnson

../../../_images/annonces_twitter_2.png

https://twitter.com/AdamChainz/status/1348295366924500993?s=20

Think of all the functions this can support!
@hannseman  has already included two very interesting examples in the
PR description:

- tsvector GIN indexes on regular columns
- B-Tree indexes on keys in JSONB columns which values are not text
Very useful

Description

The new *expressions positional argument of Index() enables creating functional indexes on expressions and database functions.

For example

 1 from django.db import models
 2 from django.db.models import F, Index, Value
 3 from django.db.models.functions import Lower, Upper
 4
 5
 6 class MyModel(models.Model):
 7     first_name = models.CharField(max_length=255)
 8     last_name = models.CharField(max_length=255)
 9     height = models.IntegerField()
10     weight = models.IntegerField()
11
12     class Meta:
13         indexes = [
14             Index(
15                 Lower('first_name'),
16                 Upper('last_name').desc(),
17                 name='first_last_name_idx',
18             ),
19             Index(
20                 F('height') / (F('weight') + Value(5)),
21                 name='calc_idx',
22             ),
23         ]

Functional indexes are added to models using the Meta.indexes option