2015-05-18 10 views
10

Sto lavorando in Django 1.8. Vorrei utilizzare lo LayerMapping import utility per aggiornare un modello esistente.Django: usa LayerMapping per aggiornare un modello esistente?

Questo è il mio file di modelli:

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

Ho già una riga nel modello con code: 03V e name: Corby, e nessun confine.

Ora voglio importare alcuni limiti per questa riga da un file KML. Questo è il mio comando di importazione:

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) 

Il problema che sto avendo è che questo sembra per pulire la riga esistente e crearne uno nuovo senza name campo. C'è un modo per aggiornare la riga usando LayerMapping, piuttosto che sovrascriverlo?

Ecco un esempio del KML, nel caso in cui questo aiuta per il test:

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

Se non posso usare LayerMapping, si prega Ci può spiegare come importare il confine dal file KML, senza l'utilizzo di LayerMapping ?

+0

Condivide la riga esistente ottenere ricreato senza 'ons_code' così come' name'? – OYRM

risposta

3

Prova ad aggiungere argomento unique. Guardando il codice sorgente LayerMapping che dovrebbe fare un aggiornamento, se il modello esiste già, ma non ho ancora testato, quindi fatemi sapere se funziona:

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

EDIT

Ma per farlo aggiorna effettivamente il campo necessario per scavalcare il metodo LayerMapping.save. Purtroppo non è possibile renderlo molto ASCIUTTO. Estendere LayerMapping e copiare tutto il codice da originali salvare e sostituire le righe 561 - 565 in questo modo:

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

Grazie per la risposta e scuse per il ritardo di risposta. Purtroppo questo ora genera il seguente errore: 'File" /Users/me/.virtualenvs/project/lib/python2.7/site-packages/django/contrib/gis/utils/layermapping.py ", riga 564, in _save geom .add (g) AttributeError: l'oggetto 'Polygon' non ha attributo 'add'' – Richard

+0

@Richard, posso vedere qual è il problema, quando si aggiorna cerca di aggiungere una nuova geometria ad una collezione di geometrie, che assume è già allegata al campo. Mi sembra un bug o una funzionalità mal progettata. Quindi l'unico modo per ottenere ciò che stai cercando di fare è personalizzare il metodo 'LayerMapping.save'. Lo aggiungerò alla risposta. –

Problemi correlati