Code

Ticket #18654: django.contrib.gis.property_fields.patch

File django.contrib.gis.property_fields.patch, 4.7 KB (added by msopacua, 21 months ago)

Add support for properties in LayerMap (fixed indentation)

  • django/contrib/gis/tests/layermap/models.py

    diff -r d4d93debc475 django/contrib/gis/tests/layermap/models.py
    a b  
    11from django.contrib.gis.db import models 
     2from django.core.exceptions import ObjectDoesNotExist 
    23 
    34class State(models.Model): 
    45    name = models.CharField(max_length=20) 
     
    4445class ICity2(ICity1): 
    4546    dt_time = models.DateTimeField(auto_now=True) 
    4647 
     48class CityHistorical(models.Model) : 
     49    name = models.CharField(max_length=25, primary_key=True) 
     50    density = models.DecimalField(max_digits=7, decimal_places=1) 
     51    dt = models.DateField() 
     52    point = models.PointField() 
     53    objects = models.GeoManager() 
     54 
     55    @property 
     56    def population(self) : 
     57        return self.pop.order_by('-year')[0].count 
     58 
     59    @population.setter 
     60    def population(self, count, year=2005) : 
     61        try : 
     62            pop = self.pop.get(year=year) 
     63        except ObjectDoesNotExist : 
     64            self.pop.create(count=count, year=year) 
     65        else : 
     66            pop.count = count 
     67            pop.save() 
     68 
     69class Population(models.Model) : 
     70    city = models.ForeignKey(CityHistorical, related_name='pop') 
     71    count = models.IntegerField() 
     72    year = models.IntegerField() 
     73 
    4774class Invalid(models.Model): 
    4875    point = models.PointField() 
    4976 
     
    6491                'point' : 'POINT', 
    6592                } 
    6693 
     94cityhistorical_mapping = {'name': 'Name', 
     95                          'density': 'Density', 
     96                          'dt': 'Created', 
     97                          'point': 'POINT', 
     98                          'population': 'Population', 
     99                         } 
     100 
    67101inter_mapping = {'name' : 'Name', 
    68102                 'length' : 'Length', 
    69103                 'path' : 'LINESTRING', 
  • django/contrib/gis/tests/layermap/tests.py

    diff -r d4d93debc475 django/contrib/gis/tests/layermap/tests.py
    a b  
    1212 
    1313from .models import ( 
    1414    City, County, CountyFeat, Interstate, ICity1, ICity2, Invalid, State, 
    15     city_mapping, co_mapping, cofeat_mapping, inter_mapping) 
     15    CityHistorical, city_mapping, cityhistorical_mapping, co_mapping, 
     16    cofeat_mapping, inter_mapping) 
    1617 
    1718 
    1819shp_path = os.path.realpath(os.path.join(os.path.dirname(__file__), os.pardir, 'data')) 
     
    281282        lm.save(silent=True, strict=True) 
    282283        self.assertEqual(City.objects.count(), 3) 
    283284        self.assertEqual(City.objects.all().order_by('name_txt')[0].name_txt, "Houston") 
     285 
     286    def test_property_field(self) : 
     287        "Tests fields implemented as properties" 
     288        mapping = copy(cityhistorical_mapping) 
     289        lm = LayerMapping(CityHistorical, city_shp, mapping) 
     290        lm.save(silent=True, strict=True) 
     291        self.assertEqual(CityHistorical.objects.count(), 3) 
     292        houston = CityHistorical.objects.get(name='Houston') 
     293        self.assertEqual(houston.population, 2144491) 
  • django/contrib/gis/utils/layermapping.py

    diff -r d4d93debc475 django/contrib/gis/utils/layermapping.py
    a b  
    178178            try: 
    179179                model_field = self.model._meta.get_field(field_name) 
    180180            except models.fields.FieldDoesNotExist: 
     181                # If the attribute is a property instance we trust that it has a setter and does the right thing(tm). 
     182                if isinstance(getattr(self.model, field_name, False), 
     183                        property) : 
     184                    self.fields[field_name] = field_name 
     185                    continue 
    181186                raise LayerMapError('Given mapping field "%s" not in given Model fields.' % field_name) 
    182187 
    183188            # Getting the string name for the Django field class (e.g., 'PointField'). 
     
    296301                # The related _model_, not a field was passed in -- indicating 
    297302                # another mapping for the related Model. 
    298303                val = self.verify_fk(feat, model_field, ogr_name) 
     304            elif isinstance(model_field, basestring) : 
     305                # The field is a model implemented property 
     306                ogr_field = feat[ogr_name] 
     307                if isinstance(ogr_field, OFTString) : 
     308                    if self.encoding : 
     309                        val = unicode(ogr_field.value, self.encoding) 
     310                    else : 
     311                        val = ogr_field.value 
     312                else : 
     313                    val = ogr_field.value 
    299314            else: 
    300315                # Otherwise, verify OGR Field type. 
    301316                val = self.verify_ogr_field(feat[ogr_name], model_field)