I am working in Django 1.8. I would like to use the LayerMapping import utility to update an existing model.
This is my models file:
class PCT(models.Model):
code = models.CharField(max_length=3, primary_key=True,
help_text='Primary care trust code')
ons_code = models.CharField(max_length=9, null=True, blank=True)
name = models.CharField(max_length=200, null=True, blank=True)
boundary = models.GeometryField(null=True, blank=True)
objects = models.GeoManager()
I already have a row in the model with code: 03V
and name: Corby
, and no boundary.
Now I want to import some boundaries for this row from a KML file. This is my import command:
class Command(BaseCommand):
args = ''
help = 'Imports boundaries from KML.'
def handle(self, *args, **options):
filename = 'CCC_Feb2013.KML'
ds = DataSource(filename)
layer_mapping = {
'code': 'Name',
'boundary': 'Unknown'
}
lm = LayerMapping(PCT, filename, layer_mapping, transform=False)
lm.save(strict=True, progress=1, verbose=True)
The problem I'm having is that this seems to wipe the existing row, and create a new one with no name
field. Is there any way to update the row using LayerMapping, rather than overwriting it?
Here's a sample of the KML, in case this helps for testing:
<?xml version="1.0" encoding="utf-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
<Folder>
<description><![CDATA[CCG boundary BSC]]></description>
<Placemark>
<name><![CDATA[03V]]></name>
<description><![CDATA[<br><br><br>
<table border="1" padding="0">
<tr><td>CCGcode</td><td>03V</td></tr>
<tr><td>CCGname</td><td>NHS Corby CCG</td></tr>
]]></description>
<visibility>1</visibility>
<open>0</open>
<Style><LineStyle><color>FF000000</color><width> 1</width></LineStyle>
<PolyStyle><fill>0</fill><outline>1</outline></PolyStyle></Style>
<Polygon>
<extrude>1</extrude>
<altitudeMode>clampToGround</altitudeMode>
<tessellate>1</tessellate>
<outerBoundaryIs><LinearRing>
<coordinates>
-.596387,52.496896,0
-.609296,52.508583,0...
</coordinates>
</LinearRing></outerBoundaryIs>
</Polygon>
</Placemark>
...
</Folder></kml>
If I can't use LayerMapping, please could you explain how to import the boundary from the KML file, without using LayerMapping?
Try adding unique
argument. Looking at the LayerMapping
source code that should do an update if model already exists, but I haven't tested it, so let me know if it works:
lm = LayerMapping(PCT, filename, layer_mapping, transform=False, unique='code')
EDIT
But for it to actually update the field it necessary to override LayerMapping.save
method. Unfortunately it is not possible to make it very DRY. Extend LayerMapping
and copy all the code from original save and replace lines 561 - 565 like so:
from django.contrib.gis.utils.layermapping import LayerMapping
class UpdateLayerMapping(LayerMapping):
def save(self, verbose=False, fid_range=False, step=False,
progress=False, silent=False, stream=sys.stdout, strict=False):
...
#geom = getattr(m, self.geom_field).ogr
#new = OGRGeometry(kwargs[self.geom_field])
#for g in new:
# geom.add(g)
#setattr(m, self.geom_field, geom.wkt)
for key, value in kwargs.iteritems():
setattr(m, key, value)
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With