diff --git a/django/contrib/gis/db/backends/spatialite/compiler.py b/django/contrib/gis/db/backends/spatialite/compiler.py
deleted file mode 100644
+
|
-
|
|
1 | | from django.db.backends.util import typecast_timestamp |
2 | | from django.db.models.sql import compiler |
3 | | from django.db.models.sql.constants import MULTI |
4 | | from django.contrib.gis.db.models.sql.compiler import GeoSQLCompiler as BaseGeoSQLCompiler |
5 | | |
6 | | SQLCompiler = compiler.SQLCompiler |
7 | | |
8 | | class GeoSQLCompiler(BaseGeoSQLCompiler, SQLCompiler): |
9 | | pass |
10 | | |
11 | | class SQLInsertCompiler(compiler.SQLInsertCompiler, GeoSQLCompiler): |
12 | | pass |
13 | | |
14 | | class SQLDeleteCompiler(compiler.SQLDeleteCompiler, GeoSQLCompiler): |
15 | | pass |
16 | | |
17 | | class SQLUpdateCompiler(compiler.SQLUpdateCompiler, GeoSQLCompiler): |
18 | | pass |
19 | | |
20 | | class SQLAggregateCompiler(compiler.SQLAggregateCompiler, GeoSQLCompiler): |
21 | | pass |
22 | | |
23 | | class SQLDateCompiler(compiler.SQLDateCompiler, GeoSQLCompiler): |
24 | | """ |
25 | | This is overridden for GeoDjango to properly cast date columns, see #16757. |
26 | | """ |
27 | | def results_iter(self): |
28 | | offset = len(self.query.extra_select) |
29 | | for rows in self.execute_sql(MULTI): |
30 | | for row in rows: |
31 | | date = typecast_timestamp(str(row[offset])) |
32 | | yield date |
diff --git a/django/contrib/gis/db/backends/spatialite/operations.py b/django/contrib/gis/db/backends/spatialite/operations.py
a
|
b
|
|
48 | 48 | return (SpatiaLiteDistance(operator),) |
49 | 49 | |
50 | 50 | class SpatiaLiteOperations(DatabaseOperations, BaseSpatialOperations): |
51 | | compiler_module = 'django.contrib.gis.db.backends.spatialite.compiler' |
| 51 | compiler_module = 'django.contrib.gis.db.models.sql.compiler' |
52 | 52 | name = 'spatialite' |
53 | 53 | spatialite = True |
54 | 54 | 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
a
|
b
|
|
1 | 1 | from itertools import izip |
2 | | from django.db.backends.util import truncate_name |
| 2 | from django.db.backends.util import truncate_name, typecast_timestamp |
3 | 3 | from django.db.models.sql import compiler |
4 | | from django.db.models.sql.constants import TABLE_NAME |
| 4 | from django.db.models.sql.constants import TABLE_NAME, MULTI |
5 | 5 | from django.db.models.sql.query import get_proxied_model |
6 | 6 | |
7 | 7 | SQLCompiler = compiler.SQLCompiler |
… |
… |
|
194 | 194 | # We resolve the rest of the columns if we're on Oracle or if |
195 | 195 | # the `geo_values` attribute is defined. |
196 | 196 | for value, field in map(None, row[index_start:], fields): |
197 | | values.append(self.query.convert_values(value, field, connection=self.connection)) |
| 197 | values.append(self.query.convert_values(value, field, self.connection)) |
198 | 198 | else: |
199 | 199 | values.extend(row[index_start:]) |
200 | 200 | return tuple(values) |
… |
… |
|
275 | 275 | pass |
276 | 276 | |
277 | 277 | class SQLDateCompiler(compiler.SQLDateCompiler, GeoSQLCompiler): |
278 | | pass |
| 278 | """ |
| 279 | This is overridden for GeoDjango to properly cast date columns, since |
| 280 | `GeoQuery.resolve_columns` is used for spatial values. |
| 281 | See #14648, #16757. |
| 282 | """ |
| 283 | def results_iter(self): |
| 284 | if self.connection.ops.oracle: |
| 285 | from django.db.models.fields import DateTimeField |
| 286 | fields = [DateTimeField()] |
| 287 | else: |
| 288 | needs_string_cast = self.connection.features.needs_datetime_string_cast |
| 289 | |
| 290 | offset = len(self.query.extra_select) |
| 291 | for rows in self.execute_sql(MULTI): |
| 292 | for row in rows: |
| 293 | date = row[offset] |
| 294 | if self.connection.ops.oracle: |
| 295 | date = self.resolve_columns(row, fields)[offset] |
| 296 | elif needs_string_cast: |
| 297 | date = typecast_timestamp(str(date)) |
| 298 | 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 68bf54c1b0d196a4e3b35d1b9045a6d8bf3f416e..893763724b819f615c09dd01e1b5705f5352d4c6
GIT binary patch
literal 526
zc$@(a0`dJHiwFSQ&TCEp1GUsoZ<{a_0PuT1#S^DZDhS&c$fg~VMpL6HUDP6_)wF{X
zyny0hWK1_S<-5-$T^dz{5vCll<o`e0kN52g;J5hztbA>K0Cc^tY-G%ZsauK*rg_Zr
z+!1ogbSg9JWz3J1i?}d@_6yWY$TZXStcUx__>)Jl|8e$pau>lndk{Dj`3NB(#Bpgz
z2zhVq=50;6y?*1smvSK2b0`j7>emnw1{mWu2)Ps_7&xBq2E+r;bx`O9ejCHP*t<}N
z_ykb|c;Ey+A%WNCpcixaPUzMF0t7ojh+P`AIojfMnd<7aA!8d}PZ*X;D)utYv=`dU
zuREg0*T%z<%#QtnwHxMM7C*TV4Vt@YqXzej*lwCHe7P<brCK$3X2V7g=@+`)JYyyV
zE4n`w?H9k@Ft@TS^dZPQXuQ9g8gp#%|J(9eDh+c}Bt0(YEvN058kRbd>ffM9@n@-E
z##VwKT~RC-buStOo=t5`tW$=zKdGx>o(hq&jX`KtH5jOCBO9G0v|YnU%Jpf0PPN$I
zf_afrafsNj^cBGN{-aEC&gnaDJ%JlpiWnl3P2fqEFe)`f3D0(w`L6GlJ#)|!797UB
z&`MT3hD8Naeh#)R&2+?$1k2X&kV{>F%s?j`rYt`P(Uw~}B6eX?Z+|26N~NnrHvkUl
Qc6;^x4;-0u?=uMi0Q%YZ6#xJL
diff --git a/django/contrib/gis/tests/relatedapp/models.py b/django/contrib/gis/tests/relatedapp/models.py
a
|
b
|
|
36 | 36 | # These use the GeoManager but do not have any geographic fields. |
37 | 37 | class Author(models.Model): |
38 | 38 | name = models.CharField(max_length=100) |
| 39 | dob = models.DateField() |
39 | 40 | objects = models.GeoManager() |
40 | 41 | |
41 | 42 | class Article(models.Model): |
diff --git a/django/contrib/gis/tests/relatedapp/tests.py b/django/contrib/gis/tests/relatedapp/tests.py
a
|
b
|
|
| 1 | from datetime import date |
1 | 2 | from django.test import TestCase |
2 | 3 | |
3 | 4 | from django.contrib.gis.geos import GEOSGeometry, Point, MultiPoint |
… |
… |
|
281 | 282 | # evaluated as list generation swallows TypeError in CPython. |
282 | 283 | sql = str(qs.query) |
283 | 284 | |
| 285 | def test16_annotated_date_queryset(self): |
| 286 | "Ensure annotated date querysets work if spatial backend is used. See #14648." |
| 287 | birth_years = [dt.year for dt in |
| 288 | list(Author.objects.annotate(num_books=Count('books')).dates('dob', 'year'))] |
| 289 | birth_years.sort() |
| 290 | self.assertEqual([1950, 1974], birth_years) |
| 291 | |
284 | 292 | # TODO: Related tests for KML, GML, and distance lookups. |