장고 쿼리 세트 (qs
)에서 특정 방식으로 extra
을 사용하면 의 결과는 len(qs.all())
과 다릅니다. 재현하려면 : 단지의 일부를 선택 extra
방법을 사용하여여분의 후 queryset의`count`가 잘못되었습니다.
>>> Baz(id=1).save()
>>> Baz(id=2).save()
>>> Baz(id=3).save()
>>> Baz(id=4).save()
:
class Baz(models.Model):
pass
지금 몇 개체를 만들 :
장고 프로젝트와 응용 프로그램 빈을 확인한 다음 사소한 모델을 추가 예상 카운트가 생성됩니다.
>>> Baz.objects.extra(where=['id > 2']).count()
2
>>> Baz.objects.extra(where=['-id < -2']).count()
2
그러나 select
extra
에 절과는 where
절에서 참조 카운트는 all()
의 결과가 정확하더라도, 갑자기 잘못 :
>>> Baz.objects.extra(select={'negid': '0 - id'}, where=['"negid" < -2']).all()
[<Baz: Baz object>, <Baz: Baz object>] # As expected
>>> Baz.objects.extra(select={'negid': '0 - id'}, where=['"negid" < -2']).count()
0 # Should be 2
나는 문제가 django.db.models.sql.query.BaseQuery.get_count()
과 관련이있다 생각합니다. BaseQuery의 select
또는 aggregate_select
속성이 설정되었는지 여부를 확인합니다. 그렇다면 하위 쿼리를 사용합니다. 그러나 django.db.models.sql.query.BaseQuery.add_extra
은 select
또는 aggregate_select
이 아닌 BaseQuery의 extra
속성에만 추가됩니다.
어떻게 문제를 해결할 수 있습니까? 나는 단지 len(qs.all())
을 사용할 수 있다는 것을 알고 있지만 extra
'ed queryset을 코드의 다른 부분으로 전달할 수 있으면 좋을 것입니다. 그리고 그 부분은 깨 졌음을 알지 못하며 count()
으로 전화 할 수 있습니다.
def get_count(self):
"""
Performs a COUNT() query using the current filter constraints.
"""
obj = self.clone()
if len(self.select) > 1 or self.aggregate_select or self.extra:
# If a select clause exists, then the query has already started to
# specify the columns that are to be returned.
# In this case, we need to use a subquery to evaluate the count.
from django.db.models.sql.subqueries import AggregateQuery
subquery = obj
subquery.clear_ordering(True)
subquery.clear_limits()
obj = AggregateQuery(obj.model, obj.connection)
obj.add_subquery(subquery)
obj.add_count_column()
number = obj.get_aggregation()[None]
# Apply offset and limit constraints manually, since using LIMIT/OFFSET
# in SQL (in variants that provide them) doesn't change the COUNT
# output.
number = max(0, number - self.low_mark)
if self.high_mark is not None:
number = min(number, self.high_mark - self.low_mark)
return number
django.db.models.sql.query.BaseQuery.get_count = quuux.get_count
테스트 : get_count()
및 monkeypatching 재정
Django 1.2.1에서 문제가 계속 발생하는지 확인했습니다. –