aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework/serializers.py
diff options
context:
space:
mode:
authorMarko Tibold2012-12-06 23:47:47 +0100
committerMarko Tibold2012-12-06 23:47:47 +0100
commitc65f22e0e4e5475aebd848b4db6b282ce524a8f3 (patch)
treebc9a30099abfca3aa11bf4969db64db2affe950c /rest_framework/serializers.py
parent899f96ae9186e68009dba5d54246232d34457354 (diff)
parent6a5f4f2a90ab19a8586a9d762c9b2618e8db5c30 (diff)
downloaddjango-rest-framework-c65f22e0e4e5475aebd848b4db6b282ce524a8f3.tar.bz2
Merge branch 'master' of https://github.com/tomchristie/django-rest-framework into #431
Diffstat (limited to 'rest_framework/serializers.py')
-rw-r--r--rest_framework/serializers.py36
1 files changed, 20 insertions, 16 deletions
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 775a8a1e..984f3ac5 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -60,7 +60,7 @@ def _get_declared_fields(bases, attrs):
# If this class is subclassing another Serializer, add that Serializer's
# fields. Note that we loop over the bases in *reverse*. This is necessary
- # in order to the correct order of fields.
+ # in order to maintain the correct order of fields.
for base in bases[::-1]:
if hasattr(base, 'base_fields'):
fields = base.base_fields.items() + fields
@@ -94,7 +94,6 @@ class BaseSerializer(Field):
def __init__(self, instance=None, data=None, files=None, context=None, partial=False, **kwargs):
super(BaseSerializer, self).__init__(**kwargs)
self.opts = self._options_class(self.Meta)
- self.fields = copy.deepcopy(self.base_fields)
self.parent = None
self.root = None
self.partial = partial
@@ -104,7 +103,7 @@ class BaseSerializer(Field):
self.init_data = data
self.init_files = files
self.object = instance
- self.default_fields = self.get_default_fields()
+ self.fields = self.get_fields()
self._data = None
self._files = None
@@ -140,13 +139,15 @@ class BaseSerializer(Field):
ret = SortedDict()
# Get the explicitly declared fields
- for key, field in self.fields.items():
+ base_fields = copy.deepcopy(self.base_fields)
+ for key, field in base_fields.items():
ret[key] = field
# Set up the field
field.initialize(parent=self, field_name=key)
# Add in the default fields
- for key, val in self.default_fields.items():
+ default_fields = self.get_default_fields()
+ for key, val in default_fields.items():
if key not in ret:
ret[key] = val
@@ -193,8 +194,7 @@ class BaseSerializer(Field):
ret = self._dict_class()
ret.fields = {}
- fields = self.get_fields()
- for field_name, field in fields.items():
+ for field_name, field in self.fields.items():
key = self.get_field_key(field_name)
value = field.field_to_native(obj, field_name)
ret[key] = value
@@ -206,9 +206,8 @@ class BaseSerializer(Field):
Core of deserialization, together with `restore_object`.
Converts a dictionary of data into a dictionary of deserialized fields.
"""
- fields = self.get_fields()
reverted_data = {}
- for field_name, field in fields.items():
+ for field_name, field in self.fields.items():
try:
field.field_from_native(data, files, field_name, reverted_data)
except ValidationError as err:
@@ -220,10 +219,7 @@ class BaseSerializer(Field):
"""
Run `validate_<fieldname>()` and `validate()` methods on the serializer
"""
- # TODO: refactor this so we're not determining the fields again
- fields = self.get_fields()
-
- for field_name, field in fields.items():
+ for field_name, field in self.fields.items():
try:
validate_method = getattr(self, 'validate_%s' % field_name, None)
if validate_method:
@@ -294,10 +290,18 @@ class BaseSerializer(Field):
Override default so that we can apply ModelSerializer as a nested
field to relationships.
"""
- obj = getattr(obj, self.source or field_name)
- if is_simple_callable(obj):
- obj = obj()
+ if self.source:
+ value = obj
+ for component in self.source.split('.'):
+ value = getattr(value, component)
+ if is_simple_callable(value):
+ value = value()
+ obj = value
+ else:
+ value = getattr(obj, field_name)
+ if is_simple_callable(value):
+ obj = value()
# If the object has an "all" method, assume it's a relationship
if is_simple_callable(getattr(obj, 'all', None)):