Changeset 5634
- Timestamp:
- 07/08/07 02:07:36 (1 year ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/gis/django/contrib/gis/utils/LayerMapping.py
r5613 r5634 21 21 model -- GeoDjango model (not an instance) 22 22 23 source_file -- OGR-supported data source file (e.g. a shapefile) 23 data -- OGR-supported data source file (e.g. a shapefile) or 24 gdal.DataSource instance 24 25 25 26 mapping -- A python dictionary, keys are strings corresponding … … 92 93 from django.contrib.gis.models import GeometryColumns, SpatialRefSys 93 94 95 from django.db import connection, transaction 96 from django.core.exceptions import ObjectDoesNotExist 97 94 98 # A mapping of given geometry types to their OGR integer type. 95 99 ogc_types = {'POINT' : OGRGeomType('Point'), … … 116 120 'POLYGON' : OGRGeomType('MultiPolygon'), 117 121 } 122 123 def map_foreign_key(django_field): 124 from django.db.models.fields.related import ForeignKey 125 126 if not django_field.__class__ is ForeignKey: 127 return django_field.__class__.__name__ 128 129 130 rf=django_field.rel.get_related_field() 131 132 return rf.get_internal_type() 118 133 119 134 # The acceptable Django field types that map to OGR fields. 120 field_types = {'IntegerField' : OFTInteger, 135 field_types = { 136 'AutoField' : OFTInteger, 137 'IntegerField' : OFTInteger, 121 138 'FloatField' : OFTReal, 122 139 'DateTimeField' : OFTDateTime, … … 143 160 144 161 # Making sure the given mapping model field is in the given model fields. 145 if not model_field in model_fields: 162 if model_field in model_fields: 163 model_type = model_fields[model_field] 164 elif model_field[:-3] in model_fields: #foreign key 165 model_type = model_fields[model_field[:-3]] 166 else: 146 167 raise Exception, 'Given mapping field "%s" not in given Model fields!' % model_field 147 else:148 model_type = model_fields[model_field]149 168 150 169 ## Handling if we get a geometry in the Field ### … … 176 195 ## Handling other fields 177 196 else: 178 # Making sure the model field is 197 # Making sure the model field is 179 198 if not model_type in field_types: 180 199 raise Exception, 'Django field type "%s" has no OGR mapping (yet).' % model_type … … 209 228 "A class that maps OGR Layers to Django Models." 210 229 211 def __init__(self, model, ogr_file, mapping, layer=0, source_srs=None):230 def __init__(self, model, data, mapping, layer=0, source_srs=None): 212 231 "Takes the Django model, the mapping (dictionary), and the SHP file." 213 232 214 233 # Getting the field names and types from the model 215 fields = dict((f.name, f.__class__.__name__) for f in model._meta.fields) 216 234 fields = dict((f.name, map_foreign_key(f)) for f in model._meta.fields) 217 235 # Getting the DataSource and its Layer 218 self.ds = DataSource(ogr_file) 236 if isinstance(data, basestring): 237 self.ds = DataSource(data) 238 else: 239 self.ds = data 219 240 self.layer = self.ds[layer] 220 241 … … 228 249 self.model = model 229 250 self.source_srs = check_srs(self.layer, source_srs) 230 251 252 @transaction.commit_on_success 231 253 def save(self, verbose=False): 232 254 "Runs the layer mapping on the given SHP file, and saves to the database." … … 247 269 except Exception, msg: 248 270 raise Exception, 'Could not translate between the data source and model geometry.' 249 271 250 272 for feat in self.layer: 251 273 # The keyword arguments for model construction … … 253 275 254 276 # Incrementing through each model field and the OGR field in the mapping 277 all_prepped = True 278 255 279 for model_field, ogr_field in self.mapping.items(): 256 model_type = self.fields[model_field] 280 is_fk = False 281 try: 282 model_type = self.fields[model_field] 283 except KeyError: #foreign key 284 model_type = self.fields[model_field[:-3]] 285 is_fk = True 257 286 258 287 if ogr_field in ogc_types: … … 272 301 273 302 # Updating the keyword args with the WKT of the transformed model. 274 kwargs[model_field]= g.wkt303 val = g.wkt 275 304 else: 276 305 ## Otherwise, this is an OGR field type 277 306 fi = feat.index(ogr_field) 278 307 val = feat[fi].value 308 309 if is_fk: 310 rel_obj = None 311 field_name = model_field[:-3] 312 try: 313 #FIXME: refactor to efficiently fetch FKs. 314 # Requires significant re-work. :-/ 315 rel = self.model._meta.get_field(field_name).rel 316 rel_obj = rel.to._default_manager.get(**{('%s__exact' % rel.field_name):val}) 317 except ObjectDoesNotExist: 318 all_prepped = False 319 320 kwargs[model_field[:-3]] = rel_obj 321 else: 279 322 kwargs[model_field] = val 280 323 281 324 # Constructing the model using the constructed keyword args 282 m = self.model(**kwargs) 283 284 # Saving the model 285 m.save() 286 if verbose: print 'Saved: %s' % str(m) 287 325 if all_prepped: 326 m = self.model(**kwargs) 327 328 # Saving the model 329 try: 330 if all_prepped: 331 m.save() 332 if verbose: print 'Saved: %s' % str(m) 333 else: 334 print "Skipping %s due to missing relation." % kwargs 335 except SystemExit: 336 raise 337 except Exception, e: 338 print "Failed to save %s\n Continuing" % kwargs 339
