Commit fb5c7748 authored by Anssi Kääriäinen's avatar Anssi Kääriäinen Committed by Claude Paroz
Browse files

Fixed #24615 -- ordering by expression not part of SELECT

Fixed queries where an expression was used in order_by() but the
expression wasn't in the query's select clause (for example the
expression could be masked by .values() call)

Thanks to Trac alias MattBlack85 for the report.
parent bcf700b4
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -12,5 +12,8 @@ class WKTAdapter(object):
            return False
        return self.wkt == other.wkt and self.srid == other.srid

    def __hash__(self):
        return hash((self.wkt, self.srid))

    def __str__(self):
        return self.wkt
+3 −0
Original line number Diff line number Diff line
@@ -28,6 +28,9 @@ class PostGISAdapter(object):
            return False
        return (self.ewkb == other.ewkb) and (self.srid == other.srid)

    def __hash__(self):
        return hash((self.ewkb, self.srid))

    def __str__(self):
        return self.getquoted()

+7 −0
Original line number Diff line number Diff line
@@ -262,10 +262,17 @@ class SQLCompiler(object):
            descending = True if order == 'DESC' else False

            if col in self.query.annotation_select:
                # Reference to expression in SELECT clause
                order_by.append((
                    OrderBy(Ref(col, self.query.annotation_select[col]), descending=descending),
                    True))
                continue
            if col in self.query.annotations:
                # References to an expression which is masked out of the SELECT clause
                order_by.append((
                    OrderBy(self.query.annotations[col], descending=descending),
                    False))
                continue

            if '.' in field:
                # This came in through an extra(order_by=...) addition. Pass it
+4 −0
Original line number Diff line number Diff line
@@ -49,3 +49,7 @@ Bugfixes
  remove usage of referencing views by dotted path in
  :func:`~django.conf.urls.url` which is deprecated in Django 1.8
  (:ticket:`24635`).

* Fixed queries where an expression was referenced in ``order_by()``, but wasn't
  part of the select clause. An example query is
  ``qs.annotate(foo=F('field')).values('pk').order_by('foo'))`` (:ticket:`24615`).
+8 −1
Original line number Diff line number Diff line
from __future__ import unicode_literals

from django.contrib.gis.geos import HAS_GEOS
from django.contrib.gis.geos import HAS_GEOS, Point
from django.contrib.gis.measure import D  # alias for Distance
from django.db import connection
from django.db.models import Q
@@ -383,3 +383,10 @@ class DistanceTest(TestCase):
        z = SouthTexasZipcode.objects.distance(htown.point).area().get(name='78212')
        self.assertIsNone(z.distance)
        self.assertIsNone(z.area)

    @skipUnlessDBFeature("has_distance_method")
    def test_distance_order_by(self):
        qs = SouthTexasCity.objects.distance(Point(3, 3)).order_by(
            'distance'
        ).values_list('name', flat=True).filter(name__in=('San Antonio', 'Pearland'))
        self.assertQuerysetEqual(qs, ['San Antonio', 'Pearland'], lambda x: x)