Ticket #10757: 10757_v2.diff

File 10757_v2.diff, 5.6 KB (added by jbronn, 15 years ago)
  • django/contrib/gis/db/models/sql/query.py

     
    7474                    table = self.alias_map[alias][TABLE_NAME]
    7575                    if table in only_load and col not in only_load[table]:
    7676                        continue
    77                     r = self.get_field_select(field, alias)
     77                    r = self.get_field_select(field, alias, column)
    7878                    if with_aliases:
    7979                        if col[1] in col_aliases:
    8080                            c_alias = 'Col%d' % len(col_aliases)
     
    112112
    113113        # This loop customized for GeoQuery.
    114114        for (table, col), field in izip(self.related_select_cols, self.related_select_fields):
    115             r = self.get_field_select(field, table)
     115            r = self.get_field_select(field, table, col)
    116116            if with_aliases and col in col_aliases:
    117117                c_alias = 'Col%d' % len(col_aliases)
    118118                result.append('%s AS %s' % (r, c_alias))
     
    213213        values = [self.convert_values(v, self.extra_select_fields.get(a, None))
    214214                  for v, a in izip(row[rn_offset:index_start], aliases)]
    215215        if SpatialBackend.oracle or getattr(self, 'geo_values', False):
    216             # We resolve the columns 
     216            # We resolve the columns
    217217            for value, field in izip(row[index_start:], fields):
    218218                values.append(self.convert_values(value, field))
    219219        else:
     
    260260            sel_fmt = sel_fmt % self.custom_select[alias]
    261261        return sel_fmt
    262262
    263     def get_field_select(self, fld, alias=None):
     263    def get_field_select(self, field, alias=None, column=None):
    264264        """
    265265        Returns the SELECT SQL string for the given field.  Figures out
    266266        if any custom selection SQL is needed for the column  The `alias`
    267267        keyword may be used to manually specify the database table where
    268268        the column exists, if not in the model associated with this
    269         `GeoQuery`.
     269        `GeoQuery`.  Similarly, `column` may be used to specify the exact
     270        column name, rather than using the `column` attribute on `field`.
    270271        """
    271         sel_fmt = self.get_select_format(fld)
    272         if fld in self.custom_select:
    273             field_sel = sel_fmt % self.custom_select[fld]
     272        sel_fmt = self.get_select_format(field)
     273        if field in self.custom_select:
     274            field_sel = sel_fmt % self.custom_select[field]
    274275        else:
    275             field_sel = sel_fmt % self._field_column(fld, alias)
     276            field_sel = sel_fmt % self._field_column(field, alias, column)
    276277        return field_sel
    277278
    278279    def get_select_format(self, fld):
     
    302303        return sel_fmt
    303304
    304305    # Private API utilities, subject to change.
    305     def _field_column(self, field, table_alias=None):
     306    def _field_column(self, field, table_alias=None, column=None):
    306307        """
    307308        Helper function that returns the database column for the given field.
    308309        The table and column are returned (quoted) in the proper format, e.g.,
    309310        `"geoapp_city"."point"`.  If `table_alias` is not specified, the
    310311        database table associated with the model of this `GeoQuery` will be
    311         used.
     312        used.  If `column` is specified, it will be used instead of the value
     313        in `field.column`.
    312314        """
    313315        if table_alias is None: table_alias = self.model._meta.db_table
    314316        return "%s.%s" % (self.quote_name_unless_alias(table_alias),
    315                           self.connection.ops.quote_name(field.column))
     317                          self.connection.ops.quote_name(column or field.column))
    316318
    317319    def _geo_field(self, field_name=None):
    318320        """
  • django/contrib/gis/tests/relatedapp/tests.py

     
    183183            self.assertEqual(m.point, d['point'])
    184184            self.assertEqual(m.point, t[1])
    185185
    186     # Test disabled until #10572 is resolved.
    187186    def test08_defer_only(self):
    188187        "Testing defer() and only() on Geographic models."
    189188        qs = Location.objects.all()
     
    191190        for loc, def_loc in zip(qs, def_qs):
    192191            self.assertEqual(loc.point, def_loc.point)
    193192
     193    def test09_pk_relations(self):
     194        "Ensuring correct primary key column is selected across relations. See #10757."
     195        # Adding two more cities, but this time making sure that their location
     196        # ID values do not match their City ID values.
     197        loc1 = Location.objects.create(point='POINT (-95.363151 29.763374)')
     198        loc2 = Location.objects.create(point='POINT (-96.801611 32.782057)')
     199        dallas = City.objects.create(name='Dallas', location=loc2)
     200        houston = City.objects.create(name='Houston', location=loc1)
     201
     202        # The expected ID values -- notice the last two location IDs
     203        # are out of order.  We want to make sure that the related
     204        # location ID column is selected instead of ID column for
     205        # the city.
     206        city_ids = (1, 2, 3, 4, 5)
     207        loc_ids = (1, 2, 3, 5, 4)
     208        ids_qs = City.objects.order_by('id').values('id', 'location__id')
     209        for val_dict, c_id, l_id in zip(ids_qs, city_ids, loc_ids):
     210            self.assertEqual(val_dict['id'], c_id)
     211            self.assertEqual(val_dict['location__id'], l_id)
     212
    194213    # TODO: Related tests for KML, GML, and distance lookups.
    195214
    196215def suite():
Back to Top