From 8b0561c57e4684ac440d36b39069a6c7f6168a02 Mon Sep 17 00:00:00 2001 From: "jedavis83@gmail.com" Date: Tue, 20 Nov 2012 23:09:47 -0800 Subject: [PATCH 1/5] Cache all fields on serializer init, not just default fields. --- rest_framework/serializers.py | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index f7918c4c3..efd564d41 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -103,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.serialize_fields = self.get_fields() self._data = None self._files = None @@ -134,7 +134,7 @@ class BaseSerializer(Field): field.initialize(parent=self, field_name=key) # Add in the default fields - for key, val in self.default_fields.items(): + for key, val in self.get_default_fields().items(): if key not in ret: ret[key] = val @@ -181,8 +181,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.serialize_fields.items(): key = self.get_field_key(field_name) value = field.field_to_native(obj, field_name) ret[key] = value @@ -194,9 +193,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.serialize_fields.items(): try: field.field_from_native(data, files, field_name, reverted_data) except ValidationError as err: @@ -208,10 +206,7 @@ class BaseSerializer(Field): """ Run `validate_()` 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.serialize_fields.items(): try: validate_method = getattr(self, 'validate_%s' % field_name, None) if validate_method: From e03bb9c2fe53591c40707569d091b8793ea1000e Mon Sep 17 00:00:00 2001 From: "jedavis83@gmail.com" Date: Tue, 20 Nov 2012 23:17:30 -0800 Subject: [PATCH 2/5] Change pagination to update Serializer.serialize_fields --- rest_framework/pagination.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py index d241ade7c..fdffec351 100644 --- a/rest_framework/pagination.py +++ b/rest_framework/pagination.py @@ -62,7 +62,7 @@ class BasePaginationSerializer(serializers.Serializer): super(BasePaginationSerializer, self).__init__(*args, **kwargs) results_field = self.results_field object_serializer = self.opts.object_serializer_class - self.fields[results_field] = object_serializer(source='object_list') + self.serialize_fields[results_field] = object_serializer(source='object_list') def to_native(self, obj): """ From e9944f82d1efd7c6bf89ca02fb9e41b9b8973129 Mon Sep 17 00:00:00 2001 From: "jedavis83@gmail.com" Date: Thu, 22 Nov 2012 10:50:29 -0800 Subject: [PATCH 3/5] Keep Serializer.fields API consistent while caching values. --- rest_framework/pagination.py | 2 +- rest_framework/serializers.py | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py index fdffec351..d241ade7c 100644 --- a/rest_framework/pagination.py +++ b/rest_framework/pagination.py @@ -62,7 +62,7 @@ class BasePaginationSerializer(serializers.Serializer): super(BasePaginationSerializer, self).__init__(*args, **kwargs) results_field = self.results_field object_serializer = self.opts.object_serializer_class - self.serialize_fields[results_field] = object_serializer(source='object_list') + self.fields[results_field] = object_serializer(source='object_list') def to_native(self, obj): """ diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index efd564d41..380c67e46 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, **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 @@ -103,7 +102,7 @@ class BaseSerializer(Field): self.init_data = data self.init_files = files self.object = instance - self.serialize_fields = self.get_fields() + self.fields = self.get_fields() self._data = None self._files = None @@ -128,7 +127,8 @@ 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) @@ -181,7 +181,7 @@ class BaseSerializer(Field): ret = self._dict_class() ret.fields = {} - for field_name, field in self.serialize_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 @@ -194,7 +194,7 @@ class BaseSerializer(Field): Converts a dictionary of data into a dictionary of deserialized fields. """ reverted_data = {} - for field_name, field in self.serialize_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: @@ -206,7 +206,7 @@ class BaseSerializer(Field): """ Run `validate_()` and `validate()` methods on the serializer """ - for field_name, field in self.serialize_fields.items(): + for field_name, field in self.fields.items(): try: validate_method = getattr(self, 'validate_%s' % field_name, None) if validate_method: From 08e7818530757fe4b5fb75ba9c6b1db2bf54ee5d Mon Sep 17 00:00:00 2001 From: "jedavis83@gmail.com" Date: Thu, 22 Nov 2012 11:27:55 -0800 Subject: [PATCH 4/5] More consistent iteration over default_fields, per feedback. --- rest_framework/serializers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 380c67e46..24fbcb79a 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -134,7 +134,8 @@ class BaseSerializer(Field): field.initialize(parent=self, field_name=key) # Add in the default fields - for key, val in self.get_default_fields().items(): + default_fields = self.get_default_fields() + for key, val in self.default_fields.items(): if key not in ret: ret[key] = val From 2e36e0c9106ad8de49ce8c169083ec1d09448458 Mon Sep 17 00:00:00 2001 From: "jedavis83@gmail.com" Date: Thu, 22 Nov 2012 12:22:30 -0800 Subject: [PATCH 5/5] Remove unneeded and incorrect self reference --- rest_framework/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 24fbcb79a..546abc061 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -135,7 +135,7 @@ class BaseSerializer(Field): # Add in the default fields default_fields = self.get_default_fields() - for key, val in self.default_fields.items(): + for key, val in default_fields.items(): if key not in ret: ret[key] = val