Commit be89c9ab authored by Justin Bronn's avatar Justin Bronn
Browse files

Fixed #12093 -- `LayerMapping` now takes into account model inheritance when...

Fixed #12093 -- `LayerMapping` now takes into account model inheritance when looking for the geometry column; forgot to diable extent regression test on MySQL. 


git-svn-id: http://code.djangoproject.com/svn/django/trunk@11703 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 1ea08b44
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ class GeoRegressionTests(unittest.TestCase):
        kmz = render_to_kmz('gis/kml/placemarks.kml', {'places' : places})

    @no_spatialite
    @no_mysql
    def test03_extent(self):
        "Testing `extent` on a table with a single point, see #11827."
        pnt = City.objects.get(name='Pueblo').point
+14 −0
Original line number Diff line number Diff line
@@ -29,6 +29,20 @@ class Interstate(models.Model):
    path = models.LineStringField()
    objects = models.GeoManager()

# Same as `City` above, but for testing model inheritance.
class CityBase(models.Model):
    name = models.CharField(max_length=25)
    population = models.IntegerField()
    density = models.DecimalField(max_digits=7, decimal_places=1)
    point = models.PointField()
    objects = models.GeoManager()

class ICity1(CityBase):
    dt = models.DateField()
    
class ICity2(ICity1):
    dt_time = models.DateTimeField(auto_now=True)

# Mapping dictionaries for the models above.
co_mapping = {'name' : 'Name',
              'state' : {'name' : 'State'}, # ForeignKey's use another mapping dictionary for the _related_ Model (State in this case).
+21 −1
Original line number Diff line number Diff line
import os, unittest
from copy import copy
from decimal import Decimal
from models import City, County, CountyFeat, Interstate, State, city_mapping, co_mapping, cofeat_mapping, inter_mapping
from models import City, County, CountyFeat, Interstate, ICity1, ICity2, State, city_mapping, co_mapping, cofeat_mapping, inter_mapping
from django.contrib.gis.db.backend import SpatialBackend
from django.contrib.gis.utils.layermapping import LayerMapping, LayerMapError, InvalidDecimal, MissingForeignKey
from django.contrib.gis.gdal import DataSource
@@ -242,6 +242,26 @@ class LayerMapTest(unittest.TestCase):
            lm.save(step=st, strict=True)
            self.county_helper(county_feat=False)

    def test06_model_inheritance(self):
        "Tests LayerMapping on inherited models.  See #12093."
        icity_mapping = {'name' : 'Name',
                         'population' : 'Population',
                         'density' : 'Density',
                         'point' : 'POINT',
                         'dt' : 'Created',
                         }

        # Parent model has geometry field.
        lm1 = LayerMapping(ICity1, city_shp, icity_mapping)
        lm1.save()

        # Grandparent has geometry field.
        lm2 = LayerMapping(ICity2, city_shp, icity_mapping)
        lm2.save()

        self.assertEqual(6, ICity1.objects.count())
        self.assertEqual(3, ICity2.objects.count())
        
def suite():
    s = unittest.TestSuite()
    s.addTest(unittest.makeSuite(LayerMapTest))
+15 −5
Original line number Diff line number Diff line
@@ -514,14 +514,24 @@ class LayerMapping(object):
    def geometry_column(self):
        "Returns the GeometryColumn model associated with the geographic column."
        from django.contrib.gis.models import GeometryColumns
        # Getting the GeometryColumn object.
        # Use the `get_field_by_name` on the model's options so that we
        # get the correct model if there's model inheritance -- otherwise
        # the returned model is None.
        opts = self.model._meta
        fld, model, direct, m2m = opts.get_field_by_name(self.geom_field)
        if model is None: model = self.model

        # Trying to get the `GeometryColumns` object that corresponds to the
        # the geometry field.
        try:
            db_table = self.model._meta.db_table
            geo_col = self.geom_field
            db_table = model._meta.db_table
            geo_col = fld.column

            if SpatialBackend.oracle:
                # Making upper case for Oracle.
                db_table = db_table.upper()
                geo_col = geo_col.upper()

            gc_kwargs = { GeometryColumns.table_name_col() : db_table,
                          GeometryColumns.geom_col_name() : geo_col,
                         }