所以我有一个查询集:
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
注释的,所以它最终被包含在count查询中。还是没有解决办法..。
发布于 2016-07-02 07:41:59
在浏览了django-rest框架代码之后,我想出了一个想法:
Paginator
类:
类RestaurantList(generics.ListAPIView):pagination_class = custom.LimitOffsetPaginationpaginator
属性:
@ paginator(self):paginator =.paginator(如果不是paginator.was_initialized():paginator.was_initialized返回分页器现在,计数查询看起来会更友好一些。
SELECT COUNT(*) AS "__count" FROM "restaurants_restaurant"
https://stackoverflow.com/questions/38152602
复制相似问题