Added value_to_native and value_from_native methods to serializer to fix #1205.

This commit is contained in:
Jannis Leidel 2013-11-04 12:34:53 +01:00
parent 003b9dda34
commit d20fa2c2c3
2 changed files with 40 additions and 16 deletions

View File

@ -144,13 +144,17 @@ class RelatedField(WritableField):
return None return None
if self.many: if self.many:
if is_simple_callable(getattr(value, 'all', None)): return self.value_to_native(value)
return [self.to_native(item) for item in value.all()] else:
else: return self.to_native(value)
# Also support non-queryset iterables.
# This allows us to also support plain lists of related items. def value_to_native(self, value):
return [self.to_native(item) for item in value] if is_simple_callable(getattr(value, 'all', None)):
return self.to_native(value) return [self.to_native(item) for item in value.all()]
else:
# Also support non-queryset iterables.
# This allows us to also support plain lists of related items.
return [self.to_native(item) for item in value]
def field_from_native(self, data, files, field_name, into): def field_from_native(self, data, files, field_name, into):
if self.read_only: if self.read_only:
@ -249,12 +253,7 @@ class PrimaryKeyRelatedField(RelatedField):
queryset = get_component(queryset, component) queryset = get_component(queryset, component)
# Forward relationship # Forward relationship
if is_simple_callable(getattr(queryset, 'all', None)): return self.value_to_native(queryset)
return [self.to_native(item.pk) for item in queryset.all()]
else:
# Also support non-queryset iterables.
# This allows us to also support plain lists of related items.
return [self.to_native(item.pk) for item in queryset]
# To-one relationship # To-one relationship
try: try:
@ -270,6 +269,14 @@ class PrimaryKeyRelatedField(RelatedField):
# Forward relationship # Forward relationship
return self.to_native(pk) return self.to_native(pk)
def value_to_native(self, value):
if is_simple_callable(getattr(value, 'all', None)):
return [self.to_native(item.pk) for item in value.all()]
else:
# Also support non-queryset iterables.
# This allows us to also support plain lists of related items.
return [self.to_native(item.pk) for item in value]
### Slug relationships ### Slug relationships

View File

@ -351,6 +351,12 @@ class BaseSerializer(WritableField):
field.label = pretty_name(key) field.label = pretty_name(key)
return field return field
def value_from_native(self, value):
return value
def value_to_native(self, value):
return value
def field_to_native(self, obj, field_name): def field_to_native(self, obj, field_name):
""" """
Override default so that the serializer can be used as a nested field Override default so that the serializer can be used as a nested field
@ -371,8 +377,9 @@ class BaseSerializer(WritableField):
except ObjectDoesNotExist: except ObjectDoesNotExist:
return None return None
if is_simple_callable(getattr(value, 'all', None)): native_value = self.value_to_native(value)
return [self.to_native(item) for item in value.all()] if native_value is not None:
return native_value
if value is None: if value is None:
return None return None
@ -407,7 +414,7 @@ class BaseSerializer(WritableField):
# Set the serializer object if it exists # Set the serializer object if it exists
obj = get_component(self.parent.object, self.source or field_name) if self.parent.object else None obj = get_component(self.parent.object, self.source or field_name) if self.parent.object else None
obj = obj.all() if is_simple_callable(getattr(obj, 'all', None)) else obj obj = self.value_from_native(obj)
if self.source == '*': if self.source == '*':
if value: if value:
@ -905,6 +912,16 @@ class ModelSerializer(Serializer):
return instance return instance
def value_from_native(self, value):
if is_simple_callable(getattr(value, 'all', None)):
return value.all()
else:
return value
def value_to_native(self, value):
if is_simple_callable(getattr(value, 'all', None)):
return [self.to_native(item) for item in value.all()]
def from_native(self, data, files): def from_native(self, data, files):
""" """
Override the default method to also include model field validation. Override the default method to also include model field validation.