Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #14648 -- Fixed annotated date querysets when `GeoManager` is u…

…sed. Thanks, codysoyland, for the bug report.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16796 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 2918c3de74d1abe571b6c1eeb35e2899c39d880e 1 parent 8e1226b
@jbronn jbronn authored
View
32 django/contrib/gis/db/backends/spatialite/compiler.py
@@ -1,32 +0,0 @@
-from django.db.backends.util import typecast_timestamp
-from django.db.models.sql import compiler
-from django.db.models.sql.constants import MULTI
-from django.contrib.gis.db.models.sql.compiler import GeoSQLCompiler as BaseGeoSQLCompiler
-
-SQLCompiler = compiler.SQLCompiler
-
-class GeoSQLCompiler(BaseGeoSQLCompiler, SQLCompiler):
- pass
-
-class SQLInsertCompiler(compiler.SQLInsertCompiler, GeoSQLCompiler):
- pass
-
-class SQLDeleteCompiler(compiler.SQLDeleteCompiler, GeoSQLCompiler):
- pass
-
-class SQLUpdateCompiler(compiler.SQLUpdateCompiler, GeoSQLCompiler):
- pass
-
-class SQLAggregateCompiler(compiler.SQLAggregateCompiler, GeoSQLCompiler):
- pass
-
-class SQLDateCompiler(compiler.SQLDateCompiler, GeoSQLCompiler):
- """
- This is overridden for GeoDjango to properly cast date columns, see #16757.
- """
- def results_iter(self):
- offset = len(self.query.extra_select)
- for rows in self.execute_sql(MULTI):
- for row in rows:
- date = typecast_timestamp(str(row[offset]))
- yield date
View
2  django/contrib/gis/db/backends/spatialite/operations.py
@@ -48,7 +48,7 @@ def get_dist_ops(operator):
return (SpatiaLiteDistance(operator),)
class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations):
- compiler_module = 'django.contrib.gis.db.backends.spatialite.compiler'
+ compiler_module = 'django.contrib.gis.db.models.sql.compiler'
name = 'spatialite'
spatialite = True
version_regex = re.compile(r'^(?P<major>\d)\.(?P<minor1>\d)\.(?P<minor2>\d+)')
View
28 django/contrib/gis/db/models/sql/compiler.py
@@ -1,7 +1,7 @@
from itertools import izip
-from django.db.backends.util import truncate_name
+from django.db.backends.util import truncate_name, typecast_timestamp
from django.db.models.sql import compiler
-from django.db.models.sql.constants import TABLE_NAME
+from django.db.models.sql.constants import TABLE_NAME, MULTI
from django.db.models.sql.query import get_proxied_model
SQLCompiler = compiler.SQLCompiler
@@ -194,7 +194,7 @@ def resolve_columns(self, row, fields=()):
# We resolve the rest of the columns if we're on Oracle or if
# the `geo_values` attribute is defined.
for value, field in map(None, row[index_start:], fields):
- values.append(self.query.convert_values(value, field, connection=self.connection))
+ values.append(self.query.convert_values(value, field, self.connection))
else:
values.extend(row[index_start:])
return tuple(values)
@@ -275,4 +275,24 @@ class SQLAggregateCompiler(compiler.SQLAggregateCompiler, GeoSQLCompiler):
pass
class SQLDateCompiler(compiler.SQLDateCompiler, GeoSQLCompiler):
- pass
+ """
+ This is overridden for GeoDjango to properly cast date columns, since
+ `GeoQuery.resolve_columns` is used for spatial values.
+ See #14648, #16757.
+ """
+ def results_iter(self):
+ if self.connection.ops.oracle:
+ from django.db.models.fields import DateTimeField
+ fields = [DateTimeField()]
+ else:
+ needs_string_cast = self.connection.features.needs_datetime_string_cast
+
+ offset = len(self.query.extra_select)
+ for rows in self.execute_sql(MULTI):
+ for row in rows:
+ date = row[offset]
+ if self.connection.ops.oracle:
+ date = self.resolve_columns(row, fields)[offset]
+ elif needs_string_cast:
+ date = typecast_timestamp(str(date))
+ yield date
View
BIN  django/contrib/gis/tests/relatedapp/fixtures/initial_data.json.gz
Binary file not shown
View
1  django/contrib/gis/tests/relatedapp/models.py
@@ -36,6 +36,7 @@ def __unicode__(self): return self.name
# These use the GeoManager but do not have any geographic fields.
class Author(models.Model):
name = models.CharField(max_length=100)
+ dob = models.DateField()
objects = models.GeoManager()
class Article(models.Model):
View
8 django/contrib/gis/tests/relatedapp/tests.py
@@ -1,3 +1,4 @@
+from datetime import date
from django.test import TestCase
from django.contrib.gis.geos import GEOSGeometry, Point, MultiPoint
@@ -281,4 +282,11 @@ def test15_invalid_select_related(self):
# evaluated as list generation swallows TypeError in CPython.
sql = str(qs.query)
+ def test16_annotated_date_queryset(self):
+ "Ensure annotated date querysets work if spatial backend is used. See #14648."
+ birth_years = [dt.year for dt in
+ list(Author.objects.annotate(num_books=Count('books')).dates('dob', 'year'))]
+ birth_years.sort()
+ self.assertEqual([1950, 1974], birth_years)
+
# TODO: Related tests for KML, GML, and distance lookups.
Please sign in to comment.
Something went wrong with that request. Please try again.