Author: jbronn
Date: 2009-04-07 16:33:43 -0500 (Tue, 07 Apr 2009)
New Revision: 10437
Modified:
django/branches/releases/1.0.X/django/contrib/gis/db/models/sql/query.py
django/branches/releases/1.0.X/django/contrib/gis/tests/relatedapp/tests.py
Log:
[1.0.X] Fixed #10757 -- Fixed improper selection of primary keys across
relations when using `GeoManager.values`. Thanks, David Gouldin for ticket and
initial patch.
Backport of r10434 from trunk.
Modified:
django/branches/releases/1.0.X/django/contrib/gis/db/models/sql/query.py
===================================================================
--- django/branches/releases/1.0.X/django/contrib/gis/db/models/sql/query.py
2009-04-07 21:21:17 UTC (rev 10436)
+++ django/branches/releases/1.0.X/django/contrib/gis/db/models/sql/query.py
2009-04-07 21:33:43 UTC (rev 10437)
@@ -66,7 +66,7 @@
# This loop customized for GeoQuery.
for col, field in izip(self.select, self.select_fields):
if isinstance(col, (list, tuple)):
- r = self.get_field_select(field, col[0])
+ r = self.get_field_select(field, col[0], col[1])
if with_aliases and col[1] in col_aliases:
c_alias = 'Col%d' % len(col_aliases)
result.append('%s AS %s' % (r, c_alias))
@@ -89,7 +89,7 @@
# This loop customized for GeoQuery.
if not self.aggregate:
for (table, col), field in izip(self.related_select_cols,
self.related_select_fields):
- r = self.get_field_select(field, table)
+ r = self.get_field_select(field, table, col)
if with_aliases and col in col_aliases:
c_alias = 'Col%d' % len(col_aliases)
result.append('%s AS %s' % (r, c_alias))
@@ -219,19 +219,20 @@
sel_fmt = sel_fmt % self.custom_select[alias]
return sel_fmt
- def get_field_select(self, fld, alias=None):
+ def get_field_select(self, field, alias=None, column=None):
"""
Returns the SELECT SQL string for the given field. Figures out
- if any custom selection SQL is needed for the column The `alias`
- keyword may be used to manually specify the database table where
- the column exists, if not in the model associated with this
- `GeoQuery`.
+ if any custom selection SQL is needed for the column The `alias`
+ keyword may be used to manually specify the database table where
+ the column exists, if not in the model associated with this
+ `GeoQuery`. Similarly, `column` may be used to specify the exact
+ column name, rather than using the `column` attribute on `field`.
"""
- sel_fmt = self.get_select_format(fld)
- if fld in self.custom_select:
- field_sel = sel_fmt % self.custom_select[fld]
+ sel_fmt = self.get_select_format(field)
+ if field in self.custom_select:
+ field_sel = sel_fmt % self.custom_select[field]
else:
- field_sel = sel_fmt % self._field_column(fld, alias)
+ field_sel = sel_fmt % self._field_column(field, alias, column)
return field_sel
def get_select_format(self, fld):
@@ -293,17 +294,18 @@
else:
return False
- def _field_column(self, field, table_alias=None):
+ def _field_column(self, field, table_alias=None, column=None):
"""
Helper function that returns the database column for the given field.
The table and column are returned (quoted) in the proper format, e.g.,
- `"geoapp_city"."point"`. If `table_alias` is not specified, the
+ `"geoapp_city"."point"`. If `table_alias` is not specified, the
database table associated with the model of this `GeoQuery` will be
- used.
+ used. If `column` is specified, it will be used instead of the value
+ in `field.column`.
"""
if table_alias is None: table_alias = self.model._meta.db_table
- return "%s.%s" % (self.quote_name_unless_alias(table_alias),
- self.connection.ops.quote_name(field.column))
+ return "%s.%s" % (self.quote_name_unless_alias(table_alias),
+ self.connection.ops.quote_name(column or
field.column))
def _geo_field(self, field_name=None):
"""
Modified:
django/branches/releases/1.0.X/django/contrib/gis/tests/relatedapp/tests.py
===================================================================
--- django/branches/releases/1.0.X/django/contrib/gis/tests/relatedapp/tests.py
2009-04-07 21:21:17 UTC (rev 10436)
+++ django/branches/releases/1.0.X/django/contrib/gis/tests/relatedapp/tests.py
2009-04-07 21:33:43 UTC (rev 10437)
@@ -95,6 +95,26 @@
# Regression test for #9752.
l = list(DirectoryEntry.objects.all().select_related())
+ def test09_pk_relations(self):
+ "Ensuring correct primary key column is selected across relations. See
#10757."
+ # Adding two more cities, but this time making sure that their location
+ # ID values do not match their City ID values.
+ loc1 = Location.objects.create(point='POINT (-95.363151 29.763374)')
+ loc2 = Location.objects.create(point='POINT (-96.801611 32.782057)')
+ dallas = City.objects.create(name='Dallas', location=loc2)
+ houston = City.objects.create(name='Houston', location=loc1)
+
+ # The expected ID values -- notice the last two location IDs
+ # are out of order. We want to make sure that the related
+ # location ID column is selected instead of ID column for
+ # the city.
+ city_ids = (1, 2, 3, 4, 5)
+ loc_ids = (1, 2, 3, 5, 4)
+ ids_qs = City.objects.order_by('id').values('id', 'location__id')
+ for val_dict, c_id, l_id in zip(ids_qs, city_ids, loc_ids):
+ self.assertEqual(val_dict['id'], c_id)
+ self.assertEqual(val_dict['location__id'], l_id)
+
# TODO: Related tests for KML, GML, and distance lookups.
def suite():
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---