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

File django.contrib.gis.property_fields.patch, 4.7 KB (added by msopacua, 3 years 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)
Back to Top