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.
This commit is contained in:
parent
bcf700b4e3
commit
fb5c7748da
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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`).
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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)
|
||||
|
|
Loading…
Reference in New Issue