gpt4 book ai didi

Django 使用注解更新查询集

转载 作者:行者123 更新时间:2023-11-28 19:35:28 26 4
gpt4 key购买 nike

我想使用注释值更新查询集中的所有行。

我有一个简单的模型:

class Relation(models.Model):
rating = models.IntegerField(default=0)

class SignRelation(models.Model):
relation = models.ForeignKey(Relation, related_name='sign_relations')
rating = models.IntegerField(default=0)

我想避开这段代码:

for relation in Relation.objects.annotate(total_rating=Sum('sign_relations__rating')):
relation.rating = relation.total_rating or 0
relation.save()

并使用类似这样的东西在一个 SQL 请求中进行更新:

Relation.objects.update(rating=Sum('sign_relations__rating'))

不起作用:

TypeError: int() argument must be a string or a number, not 'Sum'

Relation.objects.annotate(total_rating=Sum('sign_relations__rating')).update(rating=F('total_rating'))

也不起作用:

DatabaseError: missing FROM-clause entry for table "relations_signrelation"
LINE 1: UPDATE "relations_relation" SET "rating" = SUM("relations_si...

是否可以为此目的使用 Django 的 ORM?文档中没有关于一起使用 update()annotate() 的信息。

最佳答案

对于 Django 1.11+,您可以使用 Subquery :

from django.db.models import OuterRef, Subquery, Sum

Relation.objects.update(
rating=Subquery(
Relation.objects.filter(
id=OuterRef('id')
).annotate(
total_rating=Sum('sign_relations__rating')
).values('total_rating')[:1]
)
)

此代码生成与 Tomasz Jakub Rup 提出的相同 SQL 代码但没有使用 RawSQL表达。 Django 文档警告不要使用 RawSQL,因为可能会出现 SQL injection。 )

更新

我根据这个答案发表了一篇文章,其中有更深入的解释:Updating a Django queryset with annotation and subquery paulox.net

关于Django 使用注解更新查询集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3652736/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com