Ticket #17018: django-17018.2.diff

File django-17018.2.diff, 5.5 KB (added by Glen Robertson, 13 years ago)

Updated patch

  • django/contrib/gis/utils/layermapping.py

     
    295295            elif isinstance(model_field, models.base.ModelBase):
    296296                # The related _model_, not a field was passed in -- indicating
    297297                # another mapping for the related Model.
    298                 val = self.verify_fk(feat, model_field, ogr_name)
     298                fk_field = self.model._meta.get_field(field_name)
     299                val = self.verify_fk(feat, model_field, fk_field, ogr_name)
    299300            else:
    300301                # Otherwise, verify OGR Field type.
    301302                val = self.verify_ogr_field(feat[ogr_name], model_field)
     
    373374            val = ogr_field.value
    374375        return val
    375376
    376     def verify_fk(self, feat, rel_model, rel_mapping):
     377    def verify_fk(self, feat, rel_model, fk_field, rel_mapping):
    377378        """
    378379        Given an OGR Feature, the related model and its dictionary mapping,
    379380        this routine will retrieve the related model for the ForeignKey
     
    392393        try:
    393394            return rel_model.objects.using(self.using).get(**fk_kwargs)
    394395        except ObjectDoesNotExist:
    395             raise MissingForeignKey('No ForeignKey %s model found with keyword arguments: %s' % (rel_model.__name__, fk_kwargs))
     396            # When the foreign key value did not exist and
     397            # the foreign key field's configuration allows null foreign key values,
     398            # then set the foreign key value to None
     399            if fk_field.null:
     400                return None
     401            else:
     402                raise MissingForeignKey('No ForeignKey %s model found with keyword arguments: %s' % (rel_model.__name__, fk_kwargs))
    396403
    397404    def verify_geom(self, geom, model_field):
    398405        """
  • django/contrib/gis/tests/layermap/tests.py

     
    1111from django.contrib.gis.utils.layermapping import LayerMapping, LayerMapError, InvalidDecimal, MissingForeignKey
    1212
    1313from .models import (
    14     City, County, CountyFeat, Interstate, ICity1, ICity2, Invalid, State,
     14    City, County, CountyNullState, CountyFeat, Interstate, ICity1, ICity2, Invalid, State,
    1515    city_mapping, co_mapping, cofeat_mapping, inter_mapping)
    1616
    1717
    1818shp_path = os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir, 'data'))
    1919city_shp = os.path.join(shp_path, 'cities', 'cities.shp')
    2020co_shp = os.path.join(shp_path, 'counties', 'counties.shp')
     21co_shp_null_state = os.path.join(shp_path, 'counties', 'counties_null_state.shp')
    2122inter_shp = os.path.join(shp_path, 'interstates', 'interstates.shp')
    2223invalid_shp = os.path.join(shp_path, 'invalid', 'emptypoints.shp')
    2324
     
    2627NUMS   = [1, 2, 1, 19, 1] # Number of polygons for each.
    2728STATES = ['Texas', 'Texas', 'Texas', 'Hawaii', 'Colorado']
    2829
     30
    2931class LayerMapTest(TestCase):
    3032
    3133    def test01_init(self):
     
    278280        lm = LayerMapping(Invalid, invalid_shp, invalid_mapping,
    279281                          source_srs=4326)
    280282        lm.save(silent=True)
     283
     284    def test08_null_foreign_key(self):
     285        "Tests LayerMapping for models with nullable foreign keys.  See #17018."
     286        # Check that a record is successfully added with a null foreign key value when
     287        # the model foreign key field allows a null value and mapping value is null
     288        lm = LayerMapping(CountyNullState, co_shp_null_state, co_mapping, transform=False, unique='name')
     289        lm.save()
     290        self.assertEqual(1, CountyNullState.objects.all().count())
     291        county = CountyNullState.objects.all()[0]
     292        self.assertEqual('Pueblo', county.name)
     293        self.assertEqual(None, county.state)
     294        CountyNullState.objects.all().delete()
     295
     296        # Check that records are successfully added with null foreign key values when
     297        # the model foreign key field allows a null value and there is no foreign record
     298        lm = LayerMapping(CountyNullState, co_shp, co_mapping, transform=False, unique='name')
     299        lm.save()
     300        self.assertEqual(len(NAMES), CountyNullState.objects.all().count())
     301        # Ensure that all of the saved records have state set to None
     302        self.assertEqual(len(NAMES), CountyNullState.objects.filter(state=None).count())
     303
     304        # Check that MissingForeignKey is raised when
     305        # the model foreign key field does not allow a null value and mapping value is null
     306        lm = LayerMapping(County, co_shp_null_state, co_mapping, transform=False, unique='name')
     307        self.assertRaises(MissingForeignKey, lm.save, silent=True, strict=True)
  • django/contrib/gis/tests/layermap/models.py

     
    1010    mpoly = models.MultiPolygonField(srid=4269) # Multipolygon in NAD83
    1111    objects = models.GeoManager()
    1212
     13class CountyNullState(models.Model):
     14    name = models.CharField(max_length=25)
     15    state = models.ForeignKey(State, null=True)
     16    mpoly = models.MultiPolygonField(srid=4269) # Multipolygon in NAD83
     17    objects = models.GeoManager()
     18
    1319class CountyFeat(models.Model):
    1420    name = models.CharField(max_length=25)
    1521    poly = models.PolygonField(srid=4269)
Back to Top