2012-11-26 18 views
10

Aşağıdaki modelleri var:nasıl açıklamalı olan bir Sorgu Kümesi güncellenir?

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

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

Öyle gibi bazı satırları güncellemek için çalışılıyor:

DatabaseError: alt sorgu çok fazla vardır

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

Ancak bu bir hata veriyor sütunlar LINE 1: ... SET "visible" = false "app_work" NEREDE. "id" IN (SELECT ...

o madde güncelleştirir, sorgu hiçbir sorun olmadan çalışır ve ne beklediğimi döndürür. Bu hata bir güncelleme ardından bir açıklama yaparak getiren sorgular için olur gibi

görünüyor. Bunu yazmanın başka bir yolu var mı? Bir oyuncak veritabanı sorununuzu çoğaltmak ve çözümler denemek muktedir yapmadan

cevap

10

, en azından Django: Getting complement of queryset bir şekilde mümkün yaklaşımda yaklaşımını önerebilir. Bu sorunu & çoğaltılamaz ettik

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

aslında tamamlayıcı ihtiyacım yok. Sorgu doğru satırları döndürüyor, ancak sorun onları güncelleyemem. – jess

+0

Sağ. Benim amacım, toplu olarak güncellenebilir olması gereken bir açıklanmamış queryset elde etmek için aynı temel yaklaşımı kullanabilmenizdir. – acjay

+2

@jess: Sadece ne demek istediğimin bir örneğini içerecek şekilde düzenledim. Çalışırsa haberim olsun – acjay

2

Ayrıca oldukça basit bir sorgu kümesi kapalı açıklamaları temizleyebilirsiniz:

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

Ve bu yalnızca bir sorgu kapalı ateş demektir değil başka, içine kimse ama sorgu filtrelemek için bir açıklama dayanıyorsa bu kullanmayın. Bu veritabanı tarafından oluşturulan concatenations ve ben bazen modelin varsayılan sorguları içine eklemek yarar çöpleri dışarı sıyırma için harika ... ama söz konusu örnek bu işe yaramaz nerede mükemmel bir örnektir.

0

Oli cevabı eklemek için: güncelleme için daha sonra ilk filtreleri yapmak için ek açıklamalarınızı ihtiyaç ve şöyle update fonksiyona erişmek için bu sorgu kümesi üzerinde hiçbir argüman ile filtreyi çağrı sonra bir değişkene sonucunu saklamak ve varsa:

q = X.objects.filter(annotated_val=5, annotated_name='Nima') 
q.query.annotations.clear() 
q.filter().update(field=900) 
İlgili konular