mirror of
https://github.com/django/django.git
synced 2024-12-27 03:25:58 +00:00
[1.8.x] 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.
Backport of fb5c7748da
from master.
This commit is contained in:
parent
c38d8f0f87
commit
70ff455a35
@ -12,6 +12,9 @@ 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()
|
||||
|
||||
|
@ -253,10 +253,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
Block a user