2015-05-18 12 views
10

Pracuję w Django 1.8. Chciałbym użyć LayerMapping import utility, aby zaktualizować istniejący model.Django: Użyj narzędzia LayerMapping do aktualizacji istniejącego modelu?

To jest mój plik modele:

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

Mam już wiersz w modelu z code: 03V i name: Corby i bez granic.

Teraz chcę zaimportować niektóre granice dla tego wiersza z pliku KML. To jest moje polecenie import:

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) 

Problem mam jest to, że wydaje się wytrzeć istniejący wiersz, i utworzyć nowy bez name dziedzinie. Czy istnieje sposób na zaktualizowanie wiersza za pomocą LayerMapping, zamiast nadpisywania go?

Oto próbka KML, w przypadku to pomaga do testowania:

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

Jeśli nie mogę korzystać LayerMapping, proszę mógłbyś wyjaśnić, jak importować granicę z pliku KML, bez użycia LayerMapping ?

+0

Czy istniejący rząd uzyskać odtworzone bez 'ons_code' jak' name'? – OYRM

Odpowiedz

3

Spróbuj dodać argument unique. Patrząc na kod źródłowy LayerMapping że należy wykonać aktualizację modelu jeśli już istnieje, ale nie to przetestowane, więc daj mi znać, jeśli to działa:

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

EDIT

Ale za nim do faktycznie zaktualizować pole konieczne do zastąpienia metody LayerMapping.save. Niestety nie jest możliwe, aby był bardzo SUCHY. Rozszerz LayerMapping i skopiować cały kod z oryginalnego zapisać i zastąpić liniami 561 - 565 tak:

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

Dziękujemy za odpowiedź i przeprosiny za odpowiedź na opóźnienie. Niestety, teraz generuje następujący błąd: "Plik" /Users/me/.virtualenvs/project/lib/python2.7/site-packages/django/contrib/gis/utils/layermapping.py ", wiersz 564, w _save geom .add (g) AttributeError: Obiekt 'Polygon' nie ma atrybutu 'add'' – Richard

+0

@Richard, widzę, na czym polega problem, podczas aktualizacji próbuje dodać nową geometrię do kolekcji geometrii, która zakłada, że ​​jest już dołączona na pole. Wydaje mi się, że to błąd lub źle zaprojektowana funkcja. Tak więc jedynym sposobem na osiągnięcie tego, co próbujesz zrobić, jest dostosowanie metody "LayerMapping.save". Dodam to do odpowiedzi. –

Powiązane problemy