2012-11-26 4 views
10

나는 다음과 같은 모델이 있습니다주석이 달린 쿼리 세트를 업데이트하는 방법은 무엇입니까?

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

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

내가 지금처럼 일부 행을 업데이트하는 오전 :

DatabaseError의 : 하위 쿼리가 너무 많이 가지고

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

그러나이 오류가 제공됩니다 열 LINE 1 : ... SET "visible"= false "app_work". "id"IN (선택 ...

내가 제거하면 그는 쿼리 절을 실행하는데 문제가 없으며 예상 한 것을 반환합니다.

이 오류는 주석이있는 쿼리와 업데이트가 발생하는 것처럼 보입니다. 이것을 쓰는 다른 방법이 있습니까?

답변

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(..) 

그리고 이것은 당신은 단지 하나 개의 쿼리를 발사하고 의미 , 하나가 아닌 다른 하나의 필터 하지만 쿼리가 필터링을 위해 주석을 사용하는 경우이 태그를 사용하지 마십시오. 이것은 데이터베이스 생성 연결을 제거하고 모델의 기본 쿼리에 가끔 추가하는 유틸리티 쓰레기를 제거하는 데 유용합니다. 그러나이 질문의 예는 이것이 작동하지 않는 완벽한 예입니다.

0

OLI의 대답에 추가하려면 다음 업데이트에 대해 먼저 필터를 할 주석을 필요로하고 그래서 같이 update 기능에 액세스하는 데 그의 검색어에 인수없이 필터를 호출 한 후 변수에 결과를 저장하는 경우 :

q = X.objects.filter(annotated_val=5, annotated_name='Nima') 
q.query.annotations.clear() 
q.filter().update(field=900) 
관련 문제