Больше, чем индекс в Django
В Django-3.2 class Index получает позиционные аргументы выражений, которые позволяют создавать функциональные индексы по выражениям.
Можно ли создать индекс для целочисленного поля с выражением больше? Например
Моя модель:
class Product(models.Model):
description = models.CharField(max_length=50)
delivery_date = models.DateTimeField(null=True)
quantity = models.IntegerField(validators=[MinValueValidator(0)])
Обычно у меня есть фильтр (количество>0). Как создать индекс выражения для этого?
1 ответ
Решение
Вы можете использовать
ExpressionWrapper
для создания функционального индекса:
from django.db.models import BooleanField, ExpressionWrapper, Index, Q
class Product(models.Model):
# …
class Meta:
indexes = [
Index(
ExpressionWrapper(
Q(quantity__gt=0),
output_field=BooleanField()
),
name='some_name_for_the_constraint'
)
]
Что будет переведено в SQL на:
CREATE INDEX `some_name_for_the_constraint`
ON `app_name_product` ((`quantity` > 0));
Однако обычно
db_index=True
[Django-doc], будет достаточно для ускорения фильтрации, поскольку они обычно реализуются некоторой древовидной структурой и, таким образом, будут определять объекты для извлечения за O(log n).
Таким образом, мы можем установить это на:
class Product(models.Model):
# …
quantity = models.IntegerField(
db_index=True,
validators=[MinValueValidator(0)]
)
Это будет работать достаточно быстро.