2012-11-26 12 views
10

私は次のモデルがあります:注釈付きのクエリセットを更新するには?

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

class Book(models.Model): 
    work = models.ForeignKey('Work')  

私はそうのようないくつかの行を更新しようとしています:

qs=Work.objects.all() 
qs.annotate(Count('book')).filter(Q(book__count__gt=1)).update(visible=False) 

はしかし、これはエラーを与えている:

DatabaseError:副問合せは、あまりにも多くを持っています列「LINE 1:... SET "visible" = false WHERE "app_work"。 "id" IN(SELECT ...

彼は更新句、クエリは問題なく実行され、私が期待しているものを返します。

このエラーは、更新が続く注釈付きクエリのために起こるように見えます。これを書くための他の方法がありますか?

答えて

10

あなたの問題を複製し、解決策を試してみることができるようにおもちゃのデータベースをせずに、私は、少なくとも一つの可能​​なアプローチとしてDjango: Getting complement of querysetにアプローチを提案することができます。

は、このアプローチを試してみてください:

qs.annotate(Count('book')).filter(Q(book__count__gt=1)) 
Work.objects.filter(pk__in=qs.values_list('pk', flat=True)).update(visible=False) 
+0

私は実際に補完を必要としません。クエリは正しい行を返していますが、問題は私がそれらを更新できないことです。 – jess

+0

右。私の要点は、同じ基本的なアプローチを使用して、一括更新可能な注釈付きクエリセットを取得できることです。 – acjay

+2

@jess:ちょうど私が意味するものの例を含めるように編集しました。そのことがわかったら教えてください – acjay

2

また、非常に単純にクエリセットオフ注釈をクリアすることができます。

qs.query.annotations.clear() 
qs.update(..) 

そして、これはあなたが唯一のクエリをオフに発射していることをあなたのクエリは、フィルタへの注釈に依存している場合、これを使用していないではないお互いに、けど。これは、データベースが生成した連結を取り去るための素晴らしいですが、私は時折、モデルのデフォルトのクエリに追加ユーティリティのゴミ...しかし、問題の例では、これが機能しないの完璧な例です。アップデートのためにあなたの注釈が必要な場合は、最初のフィルタを実行し、結果を変数に格納し、そのようupdate機能にアクセスするためにそのクエリセットに引数なしでフィルタを呼び出します:オリの答えに追加するには

0

q = X.objects.filter(annotated_val=5, annotated_name='Nima') 
q.query.annotations.clear() 
q.filter().update(field=900) 
関連する問題