diff options
| author | José Padilla | 2014-11-28 12:14:40 -0400 |
|---|---|---|
| committer | José Padilla | 2014-11-28 12:14:40 -0400 |
| commit | 0cc990792c63caa8fa8fea62cea53b0d28157b55 (patch) | |
| tree | 7ea80a203cc8718150cd55e4403f3f4771160281 /rest_framework/utils/serializer_helpers.py | |
| parent | 1aa77830955dcdf829f65a9001b6b8900dfc8755 (diff) | |
| parent | 3a5b3772fefc3c2f2c0899947cbc07bfe6e6b5d2 (diff) | |
| download | django-rest-framework-0cc990792c63caa8fa8fea62cea53b0d28157b55.tar.bz2 | |
Merge branch 'version-3.1' into oauth_as_package
Conflicts:
requirements-test.txt
rest_framework/compat.py
tests/settings.py
tox.ini
Diffstat (limited to 'rest_framework/utils/serializer_helpers.py')
| -rw-r--r-- | rest_framework/utils/serializer_helpers.py | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/rest_framework/utils/serializer_helpers.py b/rest_framework/utils/serializer_helpers.py new file mode 100644 index 00000000..92d19857 --- /dev/null +++ b/rest_framework/utils/serializer_helpers.py @@ -0,0 +1,102 @@ +from rest_framework.compat import OrderedDict + + +class ReturnDict(OrderedDict): + """ + Return object from `serialier.data` for the `Serializer` class. + Includes a backlink to the serializer instance for renderers + to use if they need richer field information. + """ + def __init__(self, *args, **kwargs): + self.serializer = kwargs.pop('serializer') + super(ReturnDict, self).__init__(*args, **kwargs) + + def copy(self): + return ReturnDict(self, serializer=self.serializer) + + +class ReturnList(list): + """ + Return object from `serialier.data` for the `SerializerList` class. + Includes a backlink to the serializer instance for renderers + to use if they need richer field information. + """ + def __init__(self, *args, **kwargs): + self.serializer = kwargs.pop('serializer') + super(ReturnList, self).__init__(*args, **kwargs) + + +class BoundField(object): + """ + A field object that also includes `.value` and `.error` properties. + Returned when iterating over a serializer instance, + providing an API similar to Django forms and form fields. + """ + def __init__(self, field, value, errors, prefix=''): + self._field = field + self.value = value + self.errors = errors + self.name = prefix + self.field_name + + def __getattr__(self, attr_name): + return getattr(self._field, attr_name) + + @property + def _proxy_class(self): + return self._field.__class__ + + def __repr__(self): + return '<%s value=%s errors=%s>' % ( + self.__class__.__name__, self.value, self.errors + ) + + +class NestedBoundField(BoundField): + """ + This `BoundField` additionally implements __iter__ and __getitem__ + in order to support nested bound fields. This class is the type of + `BoundField` that is used for serializer fields. + """ + def __iter__(self): + for field in self.fields.values(): + yield self[field.field_name] + + def __getitem__(self, key): + field = self.fields[key] + value = self.value.get(key) if self.value else None + error = self.errors.get(key) if self.errors else None + if hasattr(field, 'fields'): + return NestedBoundField(field, value, error, prefix=self.name + '.') + return BoundField(field, value, error, prefix=self.name + '.') + + +class BindingDict(object): + """ + This dict-like object is used to store fields on a serializer. + + This ensures that whenever fields are added to the serializer we call + `field.bind()` so that the `field_name` and `parent` attributes + can be set correctly. + """ + def __init__(self, serializer): + self.serializer = serializer + self.fields = OrderedDict() + + def __setitem__(self, key, field): + self.fields[key] = field + field.bind(field_name=key, parent=self.serializer) + + def __getitem__(self, key): + return self.fields[key] + + def __delitem__(self, key): + del self.fields[key] + + def items(self): + return self.fields.items() + + def keys(self): + return self.fields.keys() + + def values(self): + return self.fields.values() |
