我试图让Django模型在降序(DESC)顺序的日期字段上创建一个索引,我找不到办法。基本上,我需要做类似下面的SQL(在Posgres中):
CREATE INDEX "idx_name" ON "table" ("date" DESC);
我最接近的是将db_index=True
添加到模型中,从而产生以下SQL:
CREATE INDEX "idx_name" ON "table" ("date");
关闭,但不是很好。 DESC在这里有很大的不同,因为我的查询返回了从最新到最旧的对象。
我知道我可以在迁移中添加原始sql,但如果Django可以为我解决这个问题会更好。
有什么想法吗?
谢谢!
答案 0 :(得分:13)
我相信你现在支持的是Django 1.11。
class Meta:
indexes = [
models.Index(fields=['last_name', 'first_name',]),
models.Index(fields=['-date_of_birth',]),
]
官方参考here,here和release notes。
答案 1 :(得分:2)
您必须使用原始SQL来根据需要创建降序索引,但有几种方法可以在不创建它的情况下实现类似的结果。
您可以通过将db_index=True
添加到字段并将ordering = ['-date']
[4]添加到模型的元数据来完成所需的功能。
如果您只是通过单个列进行排序,那么使用Django的ordering
和Postgres并不一定非常昂贵。 Postgres规划器/优化器将决定[2,3]是使用索引还是全表扫描并排序以形成关系。
要仅在单个QuerySet基础上执行排序,您可以使用order_by
[1]方法。来自Django文档:
Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')
上面的结果将按pub_date降序排序,然后按顺序排序 标题提升。 “-pub_date”前面的负号 表示降序。
使用原始SQL而不是使用原始SQL的另一种解决方案是添加索引字段,然后使用QuerySet的reverse()
[0]方法,您尝试按降序获取date
字段。这也需要db_index=True
,并且为该字段定义了默认order_by
。此方法与设置ordering
的注意事项相同,如果您根据具有不同扫描方向的多个字段进行排序,则应避免使用此方法。
另一个解决方案是覆盖默认的Django SQL模板以创建索引。该模板位于django.db.backends.base.schema.sql_create_index
[5],但如果您这样做,可能会遇到无法预料的错误。
引文,因为我无法发布两个以上的链接:https://bpaste.net/raw/6001004893c1