2015-05-18 4 views
10

Я работаю в Django 1.8. Я хотел бы использовать LayerMapping import utility для обновления существующей модели.Django: Используйте 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 ?

+0

ли существующие строки получить воссозданы без 'ons_code', а также' name'? – OYRM

ответ

3

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

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

EDIT

Но за это на самом деле обновить поле, необходимое для переопределения метода 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) 
     ... 
+0

Спасибо за ответ и извинения за ответ на задержку. К сожалению, теперь это вызывает следующую ошибку: «Файл» /Users/me/.virtualenvs/project/lib/python2.7/site-packages/django/contrib/gis/utils/layermapping.py », строка 564, в _save geom .add (g) AttributeError: объект «Polygon» не имеет атрибута «add» – Richard

+0

@ Richard, я вижу, в чем проблема, при обновлении он пытается добавить новую геометрию в коллекцию геометрий, которую он предполагает, уже прикреплен на поле. Мне кажется, как ошибка или плохо разработанная функция. Таким образом, единственный способ добиться того, что вы пытаетесь сделать, - настроить метод LayerMapping.save. Я добавлю это к ответу. –

Смежные вопросы