Django: используйте LayerMapping для обновления существующей модели?

Я работаю в Django 1.8. Я хотел бы использовать утилиту импорта LayerMapping для обновления существующей модели.

Это мой файл модели:

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()

У меня уже есть строка в модели с code: 03V и name: Corby, и никакой границы.

Теперь я хочу импортировать некоторые границы для этой строки из файла KML. Это моя команда импорта:

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)

Проблема, с которой я сталкиваюсь, заключается в том, что это, по-видимому, уничтожает существующую строку и создает новую, не имеющую поля name. Есть ли способ обновить строку, используя LayerMapping, а не переписывать ее?

Здесь образец KML, если это помогает для тестирования:

<?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>

Если я не могу использовать LayerMapping, не могли бы вы объяснить, как импортировать границу из KML файла, не используя LayerMapping?

Ответ 1

Попробуйте добавить аргумент unique. Посмотрев исходный код LayerMapping, который должен выполнить обновление, если модель уже существует, но я ее не тестировал, поэтому дайте мне знать, если она работает:

lm = LayerMapping(PCT, filename, layer_mapping, transform=False, unique='code')

ИЗМЕНИТЬ

Но для фактического обновления поля необходимо переопределить метод LayerMapping.save. К сожалению, это невозможно сделать очень сухим. Расширьте LayerMapping и скопируйте весь код из оригинального сохранения и замените строки 561 - 565:

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)
        ...