我正在尝试在Django(python)中一次更新特定顺序的所有对象的位置字段。
这就是我现在的做法,但问题在于它会产生大量查询。
servers = frontend_models.Server.objects.all().order_by('-vote_count')
i = 1
for server in servers:
server.last_rank = i
server.save()
i += 1
有没有办法用
更新Model.objects.all().order_by('some_field').update(position=some_number_that_changes_for each_object)
谢谢!
答案 0 :(得分:7)
您可以使用django.db.models
中的F()
表达式执行相同的操作:
Model.objects.all().order_by('some_field').update(position=F(some_field)+1)
将生成单个SQL查询以更新所有列值,因此它对数据库也有效。
答案 1 :(得分:0)
据我所知,Django的对象关系映射系统没有提供表达此更新操作的方法。但是如果您知道如何在SQL中表达它,那么您可以通过custom SQL query:
运行它from django.db import connection
cursor = connection.cursor()
cursor.execute('''UPDATE myapp_server ...''')
不同的数据库引擎以不同的方式表达此操作。在MySQL中,您将运行此查询:
SET @rownum=0;
UPDATE myapp_server A,
(SELECT id, @rownum := @rownum + 1 AS rank
FROM myapp_server
ORDER BY vote_count DESCENDING) B
SET A.rank = B.rank
WHERE A.id = B.id
在PostgreSQL中我认为你会使用
UPDATE myapp_server A,
(SELECT id, rownumber() AS rank
OVER (ORDER BY vote_count DESCENDING)
FROM myapp_server) B
SET A.rank = B.rank
WHERE A.id = B.id
(但这是未经测试的,所以要小心!)。