summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Bronn <jbronn@gmail.com>2011-09-10 22:53:26 +0000
committerJustin Bronn <jbronn@gmail.com>2011-09-10 22:53:26 +0000
commit2918c3de74d1abe571b6c1eeb35e2899c39d880e (patch)
treec4c9278926479916992406e24918b9f643a5f4a7
parent8e1226b4a00a0d26752b26d0ebf21ff8c5a247ad (diff)
Fixed #14648 -- Fixed annotated date querysets when `GeoManager` is used. Thanks, codysoyland, for the bug report.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16796 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/contrib/gis/db/backends/spatialite/compiler.py32
-rw-r--r--django/contrib/gis/db/backends/spatialite/operations.py2
-rw-r--r--django/contrib/gis/db/models/sql/compiler.py28
-rw-r--r--django/contrib/gis/tests/relatedapp/fixtures/initial_data.json.gzbin528 -> 526 bytes
-rw-r--r--django/contrib/gis/tests/relatedapp/models.py1
-rw-r--r--django/contrib/gis/tests/relatedapp/tests.py8
6 files changed, 34 insertions, 37 deletions
diff --git a/django/contrib/gis/db/backends/spatialite/compiler.py b/django/contrib/gis/db/backends/spatialite/compiler.py
deleted file mode 100644
index 3f81ae68a1..0000000000
--- a/django/contrib/gis/db/backends/spatialite/compiler.py
+++ /dev/null
@@ -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
diff --git a/django/contrib/gis/db/backends/spatialite/operations.py b/django/contrib/gis/db/backends/spatialite/operations.py
index 2ba54e5228..449c527187 100644
--- a/django/contrib/gis/db/backends/spatialite/operations.py
+++ b/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+)')
diff --git a/django/contrib/gis/db/models/sql/compiler.py b/django/contrib/gis/db/models/sql/compiler.py
index 782ce78368..405a000f42 100644
--- a/django/contrib/gis/db/models/sql/compiler.py
+++ b/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 @@ class GeoSQLCompiler(compiler.SQLCompiler):
# 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
diff --git a/django/contrib/gis/tests/relatedapp/fixtures/initial_data.json.gz b/django/contrib/gis/tests/relatedapp/fixtures/initial_data.json.gz
index 68bf54c1b0..893763724b 100644
--- a/django/contrib/gis/tests/relatedapp/fixtures/initial_data.json.gz
+++ b/django/contrib/gis/tests/relatedapp/fixtures/initial_data.json.gz
Binary files differ
diff --git a/django/contrib/gis/tests/relatedapp/models.py b/django/contrib/gis/tests/relatedapp/models.py
index 2e9a62b61f..aec4e15749 100644
--- a/django/contrib/gis/tests/relatedapp/models.py
+++ b/django/contrib/gis/tests/relatedapp/models.py
@@ -36,6 +36,7 @@ class Parcel(models.Model):
# 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):
diff --git a/django/contrib/gis/tests/relatedapp/tests.py b/django/contrib/gis/tests/relatedapp/tests.py
index f51f34398f..685700e9ae 100644
--- a/django/contrib/gis/tests/relatedapp/tests.py
+++ b/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 @@ class RelatedGeoModelTest(TestCase):
# 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.