2
所以我有这样的查询集:优化Django的计数()方法
from django.contrib.gis.db.models.query import GeoQuerySet
from django.db import models as base_models
class RestaurantsQuerySet(GeoQuerySet):
def get_list(self, lng, lat):
reference_point = Point(lng, lat, srid=SRID)
return self.annotate(rating=models.Avg('comments__rating'))\
.annotate(distance=Distance('location', reference_point))
def count(self):
return self.values('id').aggregate(count=base_models.Count('id'))['count']
我认为查询看起来是这样的:
SELECT COUNT("__col1")
FROM (
SELECT "restaurants_restaurant"."id" AS "__col1"
FROM "restaurants_restaurant"
GROUP BY "restaurants_restaurant"."id") subquery
,而是Django的ORM创建这个小怪物:
SELECT COUNT("__col1")
FROM (
SELECT "restaurants_restaurant"."id" AS Col1, "restaurants_restaurant"."id" AS "__col1"
FROM "restaurants_restaurant"
LEFT OUTER JOIN "comments_comment" ON ("restaurants_restaurant"."id" = "comments_comment"."restaurant_id")
GROUP BY "restaurants_restaurant"."id", ST_Distance_Sphere("restaurants_restaurant"."location",
ST_GeomFromEWKB('\x0101000020e61000003eb555a41d2d4b405a338d81d0a73240'::bytea
))) subquery
要调用的第一种方法是get_list
。它看起来好像django会“记住”那个调用,并且qs被注解为rating
和distance
,并将它也放入count
查询中。所以我想问题是 - 在注释它之前,我怎样“重置”这个查询集到状态?
编辑:
好吧,看来我的问题是不完整的。我也有定义的RestaurantsList
观点如下:
class RestaurantList(generics.ListAPIView):
def get_queryset(self):
return Restaurant.objects.get_list(self._lng, self._lat)
我接过来一看进入Django的REST的架构的内脏,我可以看到这一点:
class ListModelMixin(object):
"""
List a queryset.
"""
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
所以看起来它总是使用从get_queryset
方法返回的查询集以及由distance
和rating
注释的查询集最终包含在计数查询中。仍然没有解决这个...