#24615: ordering queryset by distance is broken
-----------------------------+--------------------------------------
     Reporter:  MattBlack85  |                    Owner:  nobody
         Type:  Bug          |                   Status:  new
    Component:  GIS          |                  Version:  1.8
     Severity:  Normal       |               Resolution:
     Keywords:               |             Triage Stage:  Unreviewed
    Has patch:  0            |      Needs documentation:  0
  Needs tests:  0            |  Patch needs improvement:  0
Easy pickings:  0            |                    UI/UX:  0
-----------------------------+--------------------------------------

Comment (by MattBlack85):

 After digging a little bit more into this I discovered this is not
 strictly related to ordering, in fact normal ordering still works:

 {{{
 In [1]: from django.contrib.gis.geos import Point

 In [2]: qs = GeoData.objects.all()

 In [3]: nqs = qs.distance(Point(3, 3)).order_by('distance')

 In [4]: nqs[0].distance
 Out[5]: Distance(m=157177.768212)
 }}}

 but when iterating the queryset ordered by distance I get the error:


 {{{
 In [1]: from django.contrib.gis.geos import Point

 In [2]: qs = GeoData.objects.all()

 In [3]: nqs = qs.distance(Point(3, 3)).order_by('distance')

 In [4]: vlqs = nqs.values_list('wisp', flat=True)

 In [5]: id_list = [id for id in vlqs]
 ---------------------------------------------------------------------------
 AttributeError                            Traceback (most recent call
 last)
 <ipython-input-5-7fa41993bc21> in <module>()
 ----> 1 id_list = [id for id in vlqs]

 /home/matt/repos/uwncom/lib/python2.7/site-
 packages/django/db/models/query.pyc in __iter__(self)
     160                - Responsible for turning the rows into model
 objects.
     161         """
 --> 162         self._fetch_all()
     163         return iter(self._result_cache)
     164

 /home/matt/repos/uwncom/lib/python2.7/site-
 packages/django/db/models/query.pyc in _fetch_all(self)
     963     def _fetch_all(self):
     964         if self._result_cache is None:
 --> 965             self._result_cache = list(self.iterator())
     966         if self._prefetch_related_lookups and not
 self._prefetch_done:
     967             self._prefetch_related_objects()

 /home/matt/repos/uwncom/lib/python2.7/site-
 packages/django/db/models/query.pyc in iterator(self)
    1215         compiler = self.query.get_compiler(self.db)
    1216         if self.flat and len(self._fields) == 1:
 -> 1217             for row in compiler.results_iter():
    1218                 yield row[0]
    1219         elif not self.query.extra_select and not
 self.query.annotation_select:

 /home/matt/repos/uwncom/lib/python2.7/site-
 packages/django/db/models/sql/compiler.pyc in results_iter(self, results)
     781         converters = None
     782         if results is None:
 --> 783             results = self.execute_sql(MULTI)
     784         fields = [s[0] for s in self.select[0:self.col_count]]
     785         converters = self.get_converters(fields)

 /home/matt/repos/uwncom/lib/python2.7/site-
 packages/django/db/models/sql/compiler.pyc in execute_sql(self,
 result_type)
     816             result_type = NO_RESULTS
     817         try:
 --> 818             sql, params = self.as_sql()
     819             if not sql:
     820                 raise EmptyResultSet

 /home/matt/repos/uwncom/lib/python2.7/site-
 packages/django/db/models/sql/compiler.pyc in as_sql(self, with_limits,
 with_col_aliases, subquery)
     365         refcounts_before = self.query.alias_refcount.copy()
     366         try:
 --> 367             extra_select, order_by, group_by =
 self.pre_sql_setup()
     368             if with_limits and self.query.low_mark ==
 self.query.high_mark:
     369                 return '', ()

 /home/matt/repos/uwncom/lib/python2.7/site-
 packages/django/db/models/sql/compiler.pyc in pre_sql_setup(self)
      47         """
      48         self.setup_query()
 ---> 49         order_by = self.get_order_by()
      50         extra_select = self.get_extra_select(order_by,
 self.select)
      51         group_by = self.get_group_by(self.select + extra_select,
 order_by)

 /home/matt/repos/uwncom/lib/python2.7/site-
 packages/django/db/models/sql/compiler.pyc in get_order_by(self)
     274                 # '-field1__field2__field', etc.
     275                 order_by.extend(self.find_ordering_name(
 --> 276                     field, self.query.get_meta(),
 default_order=asc))
     277             else:
     278                 if col not in self.query.extra_select:

 /home/matt/repos/uwncom/lib/python2.7/site-
 packages/django/db/models/sql/compiler.pyc in find_ordering_name(self,
 name, opts, alias, default_order, already_seen)
     550         # append the default ordering for that model unless the
 attribute name
     551         # of the field is specified.
 --> 552         if field.rel and path and opts.ordering and name !=
 field.attname:
     553             # Firstly, avoid infinite loops.
     554             if not already_seen:

 AttributeError: 'DistanceField' object has no attribute 'rel'
 }}}

 the model I use is very simple:

 {{{
 import uuid

 from django.contrib.gis.db import models


 class GeoData(models.Model):
     id = UUIDField(primary_key=True, editable=False, default=uuid.uuid4)
     coverage = models.MultiPolygonField(null=True, blank=True)

     objects = models.GeoManager()

     def __unicode__(self):
         return "%s" % self.coverage  # pragma: no cover
 }}}

--
Ticket URL: <https://code.djangoproject.com/ticket/24615#comment:2>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/069.2c56a71297571b4397112bc755014894%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to