web/lib/django/contrib/gis/db/models/proxy.py
changeset 29 cc9b7e14412b
parent 0 0d40e90630ef
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
     1 """
     1 """
     2  The GeometryProxy object, allows for lazy-geometries.  The proxy uses
     2 The GeometryProxy object, allows for lazy-geometries.  The proxy uses
     3  Python descriptors for instantiating and setting Geometry objects
     3 Python descriptors for instantiating and setting Geometry objects
     4  corresponding to geographic model fields.
     4 corresponding to geographic model fields.
     5 
     5 
     6  Thanks to Robert Coup for providing this functionality (see #4322).
     6 Thanks to Robert Coup for providing this functionality (see #4322).
     7 """
     7 """
     8 
     8 
     9 from types import NoneType, StringType, UnicodeType
     9 class GeometryProxy(object):
    10 
    10     def __init__(self, klass, field):
    11 class GeometryProxy(object): 
       
    12     def __init__(self, klass, field): 
       
    13         """
    11         """
    14         Proxy initializes on the given Geometry class (not an instance) and 
    12         Proxy initializes on the given Geometry class (not an instance) and
    15         the GeometryField.
    13         the GeometryField.
    16         """
    14         """
    17         self._field = field 
    15         self._field = field
    18         self._klass = klass
    16         self._klass = klass
    19      
    17 
    20     def __get__(self, obj, type=None): 
    18     def __get__(self, obj, type=None):
    21         """
    19         """
    22         This accessor retrieves the geometry, initializing it using the geometry
    20         This accessor retrieves the geometry, initializing it using the geometry
    23         class specified during initialization and the HEXEWKB value of the field.  
    21         class specified during initialization and the HEXEWKB value of the field.
    24         Currently, only GEOS or OGR geometries are supported.
    22         Currently, only GEOS or OGR geometries are supported.
    25         """
    23         """
       
    24         if obj is None:
       
    25             # Accessed on a class, not an instance
       
    26             return self
       
    27 
    26         # Getting the value of the field.
    28         # Getting the value of the field.
    27         geom_value = obj.__dict__[self._field.attname] 
    29         geom_value = obj.__dict__[self._field.attname]
    28         
    30 
    29         if isinstance(geom_value, self._klass): 
    31         if isinstance(geom_value, self._klass):
    30             geom = geom_value
    32             geom = geom_value
    31         elif (geom_value is None) or (geom_value==''):
    33         elif (geom_value is None) or (geom_value==''):
    32             geom = None
    34             geom = None
    33         else: 
    35         else:
    34             # Otherwise, a Geometry object is built using the field's contents,
    36             # Otherwise, a Geometry object is built using the field's contents,
    35             # and the model's corresponding attribute is set.
    37             # and the model's corresponding attribute is set.
    36             geom = self._klass(geom_value)
    38             geom = self._klass(geom_value)
    37             setattr(obj, self._field.attname, geom) 
    39             setattr(obj, self._field.attname, geom)
    38         return geom 
    40         return geom
    39      
    41 
    40     def __set__(self, obj, value):
    42     def __set__(self, obj, value):
    41         """
    43         """
    42         This accessor sets the proxied geometry with the geometry class
    44         This accessor sets the proxied geometry with the geometry class
    43         specified during initialization.  Values of None, HEXEWKB, or WKT may
    45         specified during initialization.  Values of None, HEXEWKB, or WKT may
    44         be used to set the geometry as well.
    46         be used to set the geometry as well.
    45         """
    47         """
    46         # The OGC Geometry type of the field.
    48         # The OGC Geometry type of the field.
    47         gtype = self._field.geom_type
    49         gtype = self._field.geom_type
    48         
    50 
    49         # The geometry type must match that of the field -- unless the
    51         # The geometry type must match that of the field -- unless the
    50         # general GeometryField is used.
    52         # general GeometryField is used.
    51         if isinstance(value, self._klass) and (str(value.geom_type).upper() == gtype or gtype == 'GEOMETRY'):
    53         if isinstance(value, self._klass) and (str(value.geom_type).upper() == gtype or gtype == 'GEOMETRY'):
    52             # Assigning the SRID to the geometry.
    54             # Assigning the SRID to the geometry.
    53             if value.srid is None: value.srid = self._field.srid
    55             if value.srid is None: value.srid = self._field.srid
    54         elif isinstance(value, (NoneType, StringType, UnicodeType)):
    56         elif value is None or isinstance(value, (basestring, buffer)):
    55             # Set with None, WKT, or HEX
    57             # Set with None, WKT, HEX, or WKB
    56             pass
    58             pass
    57         else:
    59         else:
    58             raise TypeError('cannot set %s GeometryProxy with value of type: %s' % (obj.__class__.__name__, type(value)))
    60             raise TypeError('cannot set %s GeometryProxy with value of type: %s' % (obj.__class__.__name__, type(value)))
    59 
    61 
    60         # Setting the objects dictionary with the value, and returning.
    62         # Setting the objects dictionary with the value, and returning.
    61         obj.__dict__[self._field.attname] = value 
    63         obj.__dict__[self._field.attname] = value
    62         return value 
    64         return value