如何更新已注释的查询集?

Jes*_*ess 12 django orm

我有以下型号:

class Work(models.Model):
    visible = models.BooleanField(default=False)

class Book(models.Model):
    work = models.ForeignKey('Work')    
Run Code Online (Sandbox Code Playgroud)

我试图像这样更新一些行:

qs=Work.objects.all()
qs.annotate(Count('book')).filter(Q(book__count__gt=1)).update(visible=False)
Run Code Online (Sandbox Code Playgroud)

但是,这是一个错误:

DatabaseError:子查询有太多列LINE 1:... SET"visible"= false WHERE"app_work"."id"IN(SELECT ...

如果我删除update子句,查询运行没有问题,并返回我期望的.

对于带有注释后跟更新的查询,似乎会发生此错误.有没有其他方式来写这个?

acj*_*jay 10

如果没有让玩具数据库能够复制你的问题并尝试解决方案,我至少可以在Django中建议这种方法:将查询集的补充作为一种可能的方法.

试试这种方法:

qs.annotate(Count('book')).filter(Q(book__count__gt=1))
Work.objects.filter(pk__in=qs.values_list('pk', flat=True)).update(visible=False)
Run Code Online (Sandbox Code Playgroud)

  • @jess:我刚刚编辑了一个包含我的意思的例子.如果有效,请告诉我 (2认同)

Oli*_*Oli 5

您还可以非常简单地清除查询集中的注释:

qs.query.annotations.clear()
qs.update(..)
Run Code Online (Sandbox Code Playgroud)

这意味着您只会触发一个查询,而不是一个查询,但如果您的查询依赖于要过滤的注释,请不要使用此查询.这非常适合剥离数据库生成的连接,以及我偶尔会添加到模型的默认查询中的实用程序垃圾......但问题中的示例是一个完美的例子,说明这不起作用.