diff --git a/django/contrib/gis/utils/layermapping.py b/django/contrib/gis/utils/layermapping.py index e4baf56dcb..b184de53ef 100644 --- a/django/contrib/gis/utils/layermapping.py +++ b/django/contrib/gis/utils/layermapping.py @@ -558,10 +558,14 @@ class LayerMapping: # one from the kwargs WKT, adding in additional # geometries, and update the attribute with the # just-updated geometry WKT. - geom = getattr(m, self.geom_field).ogr - new = OGRGeometry(kwargs[self.geom_field]) - for g in new: - geom.add(g) + geom_value = getattr(m, self.geom_field) + if geom_value is None: + geom = OGRGeometry(kwargs[self.geom_field]) + else: + geom = geom_value.ogr + new = OGRGeometry(kwargs[self.geom_field]) + for g in new: + geom.add(g) setattr(m, self.geom_field, geom.wkt) except ObjectDoesNotExist: # No unique model exists yet, create. diff --git a/tests/gis_tests/layermap/models.py b/tests/gis_tests/layermap/models.py index 9b05056f4e..de1dd6c944 100644 --- a/tests/gis_tests/layermap/models.py +++ b/tests/gis_tests/layermap/models.py @@ -17,7 +17,7 @@ class State(NamedModel): class County(NamedModel): state = models.ForeignKey(State, models.CASCADE) - mpoly = models.MultiPolygonField(srid=4269) # Multipolygon in NAD83 + mpoly = models.MultiPolygonField(srid=4269, null=True) # Multipolygon in NAD83 class CountyFeat(NamedModel): diff --git a/tests/gis_tests/layermap/tests.py b/tests/gis_tests/layermap/tests.py index 2406533e66..a1b288eafa 100644 --- a/tests/gis_tests/layermap/tests.py +++ b/tests/gis_tests/layermap/tests.py @@ -310,6 +310,17 @@ class LayerMapTest(TestCase): self.assertEqual(City.objects.count(), 1) self.assertEqual(City.objects.all()[0].name, "Zürich") + def test_null_geom_with_unique(self): + """LayerMapping may be created with a unique and a null geometry.""" + State.objects.bulk_create([State(name='Colorado'), State(name='Hawaii'), State(name='Texas')]) + hw = State.objects.get(name='Hawaii') + hu = County.objects.create(name='Honolulu', state=hw, mpoly=None) + lm = LayerMapping(County, co_shp, co_mapping, transform=False, unique='name') + lm.save(silent=True, strict=True) + hu.refresh_from_db() + self.assertIsNotNone(hu.mpoly) + self.assertEqual(hu.mpoly.ogr.num_coords, 449) + class OtherRouter: def db_for_read(self, model, **hints):