From 86c209cf6008a4da8e48385e09c8cc4836972295 Mon Sep 17 00:00:00 2001 From: Mjumbe Wawatu Ukweli Date: Thu, 11 Jul 2013 20:08:15 -0400 Subject: [PATCH] Add Field.many_to_native for more control over iterable serialization --- rest_framework/fields.py | 8 +++++++- rest_framework/relations.py | 4 ++-- rest_framework/serializers.py | 6 +++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/rest_framework/fields.py b/rest_framework/fields.py index 0a199f102..94e6ae5e8 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -160,11 +160,17 @@ class Field(object): if is_protected_type(value): return value elif hasattr(value, '__iter__') and not isinstance(value, (dict, six.string_types)): - return [self.to_native(item) for item in value] + return self.many_to_native(value) elif isinstance(value, dict): return dict(map(self.to_native, (k, v)) for k, v in value.items()) return smart_text(value) + def many_to_native(self, many_values, key_func=(lambda value: value)): + """ + Return a list of many simple objects. + """ + return [self.to_native(key_func(value)) for value in many_values] + def attributes(self): """ Returns a dictionary of attributes to be used when serializing to xml. diff --git a/rest_framework/relations.py b/rest_framework/relations.py index 2a10e9af5..49910de8e 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -133,7 +133,7 @@ class RelatedField(WritableField): return None if self.many: - return [self.to_native(item) for item in value.all()] + return self.many_to_native(value.all()) return self.to_native(value) def field_from_native(self, data, files, field_name, into): @@ -223,7 +223,7 @@ class PrimaryKeyRelatedField(RelatedField): queryset = getattr(obj, self.source or field_name) # Forward relationship - return [self.to_native(item.pk) for item in queryset.all()] + return self.many_to_native(queryset.all(), lambda item: item.pk) # To-one relationship try: diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 2ae7c215f..d9e5df3c7 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -317,7 +317,7 @@ class BaseSerializer(Field): # If the object has an "all" method, assume it's a relationship if is_simple_callable(getattr(obj, 'all', None)): - return [self.to_native(item) for item in obj.all()] + return self.many_to_native(obj.all()) if obj is None: return None @@ -328,7 +328,7 @@ class BaseSerializer(Field): many = hasattr(obj, '__iter__') and not isinstance(obj, (Page, dict, six.text_type)) if many: - return [self.to_native(item) for item in obj] + return self.many_to_native(obj) return self.to_native(obj) @property @@ -385,7 +385,7 @@ class BaseSerializer(Field): PendingDeprecationWarning, stacklevel=2) if many: - self._data = [self.to_native(item) for item in obj] + self._data = self.many_to_native(obj) else: self._data = self.to_native(obj)