So habe ich diese queryset:Optimierung Djangos count() -Methode
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']
Ich dachte, dass die Abfrage etwas aussehen würde:
SELECT COUNT("__col1")
FROM (
SELECT "restaurants_restaurant"."id" AS "__col1"
FROM "restaurants_restaurant"
GROUP BY "restaurants_restaurant"."id") subquery
Und statt django ORM schafft diese kleine Ungeheuerlichkeit:
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
Die erste aufgerufene Methode ist get_list
. Es sieht so aus, als ob sich der Django an diesen Aufruf "erinnern" würde und dass das Qs mit rating
und distance
annotiert wurde und es ebenfalls in die count
Abfrage platziert. Ich denke also, die Frage ist - wie setze ich dieses Queryset in den Zustand zurück, bevor ich es annotiere?
EDIT:
Okay, scheint meine Frage nicht vollständig war. Ich habe auch eine RestaurantsList
Ansicht wie folgt definiert:
class RestaurantList(generics.ListAPIView):
def get_queryset(self):
return Restaurant.objects.get_list(self._lng, self._lat)
Ich warf einen Blick ins Innere der django-Rest-Rahmen und ich kann diese sehen:
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)
So sieht es aus wie es immer verwendet das Abfrage-Set, das von der get_queryset
-Methode zurückgegeben wurde, und seit es mit distance
und rating
annotiert ist, wird es in der Count-Abfrage enthalten. Immer noch keine Lösung dieses ...