django - Django 根据查询集中的顺序更新行
问题描述
我有一个简单的 django 模型
class Item(Model):
name = CharField()
rank = PositiveIntegerField()
created_at = DateField(auto_now_add=True)
我想在按字段(名称或created_at)排序时根据它们的顺序更新对象等级,例如按名称排序时
[("Pen", 0, "2021-05-04"), ("Ball", 0, "2021-05-04")] => [("Pen", 1, "2021-05-04"), (Ball, 0, "2021-05-04")]
我已经知道我可以使用 bulk_update 来做到这一点,但这意味着我必须获取内存中的对象
items = Items.objects.order_by("name")
for i, item in enumerate(items):
item.rank = i
Item.objects.bulk_update(items, ["rank"])
我想知道是否有一种方法可以直接在数据库中进行 1 个查询,而无需获取数据
解决方案
CREATE TABLE items (
id serial PRIMARY KEY,
name VARCHAR ( 50 ) UNIQUE NOT NULL,
rank smallint
);
insert into items(id, name, rank) values (1, 'A', 0);
insert into items(id, name, rank) values (2, 'B', 0);
insert into items(id, name, rank) values (3, 'C', 0);
select * from items;
ID | 姓名 | 秩 |
---|---|---|
1 | 一个 | 0 |
2 | 乙 | 0 |
3 | C | 0 |
UPDATE items
SET rank=calculated.calc_rank
FROM
(SELECT id AS calc_id,
(ROW_NUMBER() OVER (
ORDER BY name ASC)) AS calc_rank
FROM items) AS calculated
WHERE items.id = calculated.calc_id;
select * from items;
ID | 姓名 | 秩 |
---|---|---|
1 | 一个 | 1 |
2 | 乙 | 2 |
3 | C | 3 |
sql = '''
UPDATE items
SET rank=calculated.calc_rank
FROM
(SELECT id AS calc_id,
(ROW_NUMBER() OVER (
ORDER BY name ASC)) AS calc_rank
FROM items) AS calculated
WHERE items.id = calculated.calc_id
'''
with connection.cursor() as cursor:
cursor.execute(sql)
推荐阅读
- kubernetes-helm - fluentd gelf插件参数设置
- c# - 从 ILogger 在控制台中显示日志对象
日志关键 - python - 什么是 sklearn.linear_model 中的 .linear_model
- canvas - 使用画布处理 getDispaymedia 流时,无法以原始分辨率传输。- 网络RTC
- javascript - 如何正确推送我的 ReactJS gh-pages?
- javascript - 如何在变量中分配逻辑或运算符
- javascript - Workbox Service Worker 不保存缓存
- javascript - 碰撞仅针对最后一个 DIV 触发
- asp.net-mvc - 在 Web API c# MVC 中使用 HttpActionExecutedContext 时出现缓存问题
- laravel - 在 Laravel 5.7 中动态合并 .env 文件旧键值