Merge pull request #433 from irrelative/master

Cache default_fields per serializer instance for faster serialization
This commit is contained in:
Tom Christie 2012-11-20 15:13:30 -08:00
commit 9b63ba3800

View File

@ -103,6 +103,7 @@ class BaseSerializer(Field):
self.init_data = data self.init_data = data
self.init_files = files self.init_files = files
self.object = instance self.object = instance
self.default_fields = self.get_default_fields()
self._data = None self._data = None
self._files = None self._files = None
@ -111,18 +112,18 @@ class BaseSerializer(Field):
##### #####
# Methods to determine which fields to use when (de)serializing objects. # Methods to determine which fields to use when (de)serializing objects.
def default_fields(self, nested=False): def get_default_fields(self):
""" """
Return the complete set of default fields for the object, as a dict. Return the complete set of default fields for the object, as a dict.
""" """
return {} return {}
def get_fields(self, nested=False): def get_fields(self):
""" """
Returns the complete set of fields for the object as a dict. Returns the complete set of fields for the object as a dict.
This will be the set of any explicitly declared fields, This will be the set of any explicitly declared fields,
plus the set of fields returned by default_fields(). plus the set of fields returned by get_default_fields().
""" """
ret = SortedDict() ret = SortedDict()
@ -133,8 +134,7 @@ class BaseSerializer(Field):
field.initialize(parent=self, field_name=key) field.initialize(parent=self, field_name=key)
# Add in the default fields # Add in the default fields
fields = self.default_fields(nested) for key, val in self.default_fields.items():
for key, val in fields.items():
if key not in ret: if key not in ret:
ret[key] = val ret[key] = val
@ -181,7 +181,7 @@ class BaseSerializer(Field):
ret = self._dict_class() ret = self._dict_class()
ret.fields = {} ret.fields = {}
fields = self.get_fields(nested=bool(self.opts.depth)) fields = self.get_fields()
for field_name, field in fields.items(): for field_name, field in fields.items():
key = self.get_field_key(field_name) key = self.get_field_key(field_name)
value = field.field_to_native(obj, field_name) value = field.field_to_native(obj, field_name)
@ -194,7 +194,7 @@ class BaseSerializer(Field):
Core of deserialization, together with `restore_object`. Core of deserialization, together with `restore_object`.
Converts a dictionary of data into a dictionary of deserialized fields. Converts a dictionary of data into a dictionary of deserialized fields.
""" """
fields = self.get_fields(nested=bool(self.opts.depth)) fields = self.get_fields()
reverted_data = {} reverted_data = {}
for field_name, field in fields.items(): for field_name, field in fields.items():
try: try:
@ -209,7 +209,7 @@ class BaseSerializer(Field):
Run `validate_<fieldname>()` and `validate()` methods on the serializer Run `validate_<fieldname>()` and `validate()` methods on the serializer
""" """
# TODO: refactor this so we're not determining the fields again # TODO: refactor this so we're not determining the fields again
fields = self.get_fields(nested=bool(self.opts.depth)) fields = self.get_fields()
for field_name, field in fields.items(): for field_name, field in fields.items():
try: try:
@ -335,16 +335,10 @@ class ModelSerializer(Serializer):
""" """
_options_class = ModelSerializerOptions _options_class = ModelSerializerOptions
def default_fields(self, nested=False): def get_default_fields(self):
""" """
Return all the fields that should be serialized for the model. Return all the fields that should be serialized for the model.
""" """
# TODO: Modify this so that it's called on init, and drop
# serialize/obj/data arguments.
#
# We *could* provide a hook for dynamic fields, but
# it'd be nice if the default was to generate fields statically
# at the point of __init__
cls = self.opts.model cls = self.opts.model
opts = get_concrete_model(cls)._meta opts = get_concrete_model(cls)._meta
@ -356,6 +350,7 @@ class ModelSerializer(Serializer):
fields += [field for field in opts.many_to_many if field.serialize] fields += [field for field in opts.many_to_many if field.serialize]
ret = SortedDict() ret = SortedDict()
nested = bool(self.opts.depth)
is_pk = True # First field in the list is the pk is_pk = True # First field in the list is the pk
for model_field in fields: for model_field in fields: