Usage
Example
from composite_field import CompositeField
class CoordField(CompositeField):
x = models.FloatField()
y = models.FloatField()
class Place(models.Model):
name = models.CharField(max_length=10)
coord = CoordField()
p = Place(name='Foo', coord_x=42, coord_y=0)
q = Place(name='Foo', coord=p.coord)
q.coord.y = 42
How does it work?
The content of composite fields are stored inside the model, so they do
not have to fiddle with any internals of the Django models. In the example
above p.coord
returns a proxy object that maps the fields x
and y
to the model fields coord_x
and coord_y
.
This is roughly equivalent to the following code:
class CoordProxy:
def __init__(self, model):
self.model = model
def __get__(self, instance):
return CoordProxy(instance)
def __set__(self, instance, value):
instance.coord_x = value.coord_x
instance.coord_y = value.coord_y
@property
def x(self):
return self.model.coord_x
@x.setter
def x(self, value):
self.model.coord_x = value
@property
def y(self):
return self.model.coord_y
@y.setter
def y(self, value):
self.model.coord_y = value
class Place(models.Model):
name = models.CharField(max_length=10)
coord_x = models.FloatField()
coord_y = models.FloatField()
coord = CoordProxy()
Advanced usage
The proxy object also makes it possible to assign more than one property at once:
place1.coord = place2.coord
It also supports using dictionaries for the __init__
method or
assigning them as a value:
place1 = Place(coord={'x': 42, 'y': 0})
place1.coord = {'x': 43, 'y': 1}
It is even possible to replace the Proxy
object entirely and
return a custom type. A good example for this is the included
ComplexField
which stores a complex
number in two
integer fields.