如何在Django中通过单条数据库查询更新排序后对象的rank值
Django无需拉取数据批量更新排序后rank字段的方案
直接使用Django内置的窗口函数+更新语句即可实现单条数据库查询完成需求,无需加载全量数据到内存:
首先导入依赖:
from django.db.models import F, Window from django.db.models.functions import RowNumber
按name升序排序更新rank示例
Item.objects.update( rank=Window( expression=RowNumber(), order_by=F("name").asc() ) - 1 # 减去1是因为RowNumber默认从1开始计数,适配你示例中从0开始的rank规则 )
如果需要按created_at排序,仅需修改order_by参数的字段即可,需要降序排序则将.asc()替换为.desc()。
注意事项
- 该方案完全在数据库层面执行,仅发起一次更新请求,数据量越大相比
bulk_update方案的性能优势越明显,无内存溢出风险 - 依赖环境支持:Django版本≥2.0,数据库需支持窗口函数(PostgreSQL全版本支持、MySQL≥8.0、SQLite≥3.25)
- 若不需要从0开始计数,去掉代码中的
-1即可,RowNumber会直接返回从1开始的排序序号
内容的提问来源于stack exchange,提问作者Martin Faucheux
相关产品推荐
相关产品推荐

