title: Optimizing djangos count() method
body: <p>So I have this queryset:</p>
  
  <pre><code>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']
  </code></pre>
  
  <p>I thought that the query would look something like: </p>
  
  <pre><code>SELECT COUNT("__col1") 
  FROM (
      SELECT "restaurants_restaurant"."id" AS "__col1" 
      FROM "restaurants_restaurant" 
      GROUP BY "restaurants_restaurant"."id") subquery
  </code></pre>
  
  <p>And instead django orm creates this little monstrosity:</p>
  
  <pre><code>    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
  </code></pre>
  
  <p>First method to be called is <code>get_list</code>. It looks as if django would "remember" that call and that the qs was annotated with <code>rating</code> and <code>distance</code> and places it also into the <code>count</code> query. So I guess the question is - how do I "reset" this queryset to the state before annotating it?</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>Okay, seems my question was not complete. I also have a <code>RestaurantsList</code> view defined as follows:</p>
  
  <pre><code>class RestaurantList(generics.ListAPIView):
      def get_queryset(self):
          return Restaurant.objects.get_list(self._lng, self._lat)
  </code></pre>
  
  <p>I took a look into the entrails of django-rest-framework and I can see this:</p>
  
  <pre><code>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)
  </code></pre>
  
  <p>So it looks like it always uses the queryset that was returned from the <code>get_queryset</code> method and since it's annotated with <code>distance</code> and <code>rating</code> it ends up being included in the count query. Still no solution to this...</p>