如何在 django 2.2 模型中创建部分索引

问题描述

我在 Django 2.2 中有一个这样的模型

class Post(models.Model):
    class Meta:
        verbose_name = _('Post')
        verbose_name_plural = _('Posts')

    phone_number = models.CharField(max_length=11,verbose_name=_('Phone number'),db_index=True)

    token = models.CharField(unique=True,max_length=20,verbose_name=_('Token'),db_index=True)
 
    post_state = models.SmallIntegerField(choices=[
        (PostState.NEW,_('New')),(PostState.PUBLISHED,_('Published')),(PostState.ARCHIVED,_('Archive')),(PostState.REMOVED_BEFORE_PUBLISH,_('Removed before publish')),(PostState.REJECTED_AFTER_PUBLISH,_('Rejected after publish')),],default=PostState.NEW,verbose_name=_('Post state'),db_index=True)
    

我希望我在 phone_number 和 token 上的索引是基于 post_state 值的部分索引,我知道如何在 Postgres shell 中使用 sql 命令来执行它,但我不知道如何在 django 模型中执行它所以它进入还有一个迁移文件

解决方法

所以我找到了这个问题的答案。

class Post(models.Model):
    class Meta:
        verbose_name = _('Post')
        verbose_name_plural = _('Posts')
        indexes = (
            BTreeIndex(fields=('token',),condition=Q(post_state__in=[PostState.NEW,PostState.PUBLISHED])),)

    phone_number = models.CharField(max_length=11,verbose_name=_('Phone number'),db_index=True)

    token = models.CharField(unique=True,max_length=20,verbose_name=_('Token'))
 
    post_state = models.SmallIntegerField(choices=[
        (PostState.NEW,_('New')),(PostState.PUBLISHED,_('Published')),(PostState.ARCHIVED,_('Archive')),(PostState.REMOVED_BEFORE_PUBLISH,_('Removed before publish')),(PostState.REJECTED_AFTER_PUBLISH,_('Rejected after publish')),],default=PostState.NEW,verbose_name=_('Post state'))

我们在模型的 Meta 部分创建索引,它有一个条件参数,您可以在其中传递部分条件。

,

Django indexesindex options,您可以简单地向模型元类添加索引:

from django.db.models import Index

class Meta:
        indexes = [
            Index(fields=['phone_number',Index(fields=['token',... # other indexes
        ]