Fields¶
The field decorator¶
The field decorator works exactly like property, however it will operate on the “bound” object, not the Mapper.
-
class
field
¶ Parameters: - required – Is this field required? Default: True
- default – The value to use if the source value is absent. May be a callable that takes no arguments.
- readonly – Can the field be updated? Default: True
- null – Is None a valid valie? Default: False
The decorator can be used bare, or with arguments:
class M(Mapper):
@mapper.field
def foo(self):
return self.bar
@mapper.field(default=0)
def baz(self):
return self.qux
@baz.setter
def baz(self, value):
self.qux = value
As you can see, both the getter and setter of a field are defined the same way as with property.
Basic fields¶
For simple cases where the descriptor protocol is overkill, there is the Field class.
-
class
Field
(...)¶ Parameters: - attr – The name of the attribute on the bound object it gets/sets.
- required – Is this field required? Default: True
- default – The value to use if the source value is absent.
- readonly – Can the field be updated? Default: True
- null – Is None a valid valie? Default: False
class M(Mapper):
foo = Field('bar')
baz = Field('qux', default=0)
There are also typed fields:
- BooleanField
- IntegerField
- FloatField
- TimeField
- DateField
- DateTimeField
These will ensure the values stored are of the correct type, as well as being presented to JSON in a usable format.
Accessing extra state¶
Sometimes when serialising an object, you need to provide additional state.
This can be done using a context_field
, which subclasses field
, but
passes any extra kwargs
that were pased to Mapper instance context to
the getter and setter methods as an extra argument.
-
class
context_field
¶ Parameters: - required – Is this field required? Default: True
- default – The value to use if the source value is absent.
- readonly – Can the field be updated? Default: True
- null – Is None a valid valie? Default: False
The following is an example from the test suite:
class M(Mapper):
@fields.context_field
def scaled(self, context):
return self.value * context['factor']
@scaled.setter
def scaled(self, value, context):
obj.value = value // self._context['factor']
m = M(o, factor=10)
Accessing m.scaled
will now return the value multiplied by 10.
Models¶
Relation Fields¶
To help with relations, the models module includes two extra field types:
- ToOneField
- ToManyField
Both accept the same extra arguments:
-
class
RelatedField
¶ Parameters: - model – The model this field relates to
- mapper – (Optional) the mapper to use to reduce instances.
When the mapper is omitted, only the Primary Key of the related model will be used.
The ToManyField
will work on any iterable, however if it’s passed a
Manager
it will call .all()
before iterating it. This makes it ideally
suited for ManyToMany
and reverse ForeignKey
accessors.