mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-03 12:00:12 +03:00
Updates for pull request review comments
* Remove ListOrObjectField * Allow item_field & value_field to be optional * Undo from_native API change; flex invocation in compound fields * In DictField, coerce key to a string * If list or dict is None or empty, just return input preserving empty containers * Remove dict comprehension for Python 2.6 compat
This commit is contained in:
parent
0e8760eaaf
commit
b0027e52fa
71
rest_framework/compound_fields.py
Normal file
71
rest_framework/compound_fields.py
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
"""
|
||||||
|
Compound fields for processing values that are lists and dicts of values described by embedded
|
||||||
|
fields.
|
||||||
|
"""
|
||||||
|
from .fields import WritableField
|
||||||
|
from .serializers import BaseSerializer
|
||||||
|
|
||||||
|
|
||||||
|
def field_or_serializer_from_native(field_or_serializer, data):
|
||||||
|
if isinstance(field_or_serializer, BaseSerializer):
|
||||||
|
return field_or_serializer.from_native(data, None)
|
||||||
|
return field_or_serializer.from_native(data)
|
||||||
|
|
||||||
|
|
||||||
|
class ListField(WritableField):
|
||||||
|
"""
|
||||||
|
A field whose values are lists of items described by the given item field. The item field can
|
||||||
|
be another field type (e.g., CharField) or a serializer.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, item_field=None, *args, **kwargs):
|
||||||
|
super(ListField, self).__init__(*args, **kwargs)
|
||||||
|
self.item_field = item_field
|
||||||
|
|
||||||
|
def to_native(self, obj):
|
||||||
|
if obj:
|
||||||
|
return [
|
||||||
|
self.item_field.to_native(item) if self.item_field else item
|
||||||
|
for item in obj
|
||||||
|
]
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def from_native(self, data):
|
||||||
|
if data:
|
||||||
|
return [
|
||||||
|
field_or_serializer_from_native(self.item_field, item_data)
|
||||||
|
if self.item_field else item_data
|
||||||
|
for item_data in data
|
||||||
|
]
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
class DictField(WritableField):
|
||||||
|
"""
|
||||||
|
A field whose values are dicts of values described by the given value field. The value field
|
||||||
|
can be another field type (e.g., CharField) or a serializer.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, value_field=None, *args, **kwargs):
|
||||||
|
super(DictField, self).__init__(*args, **kwargs)
|
||||||
|
self.value_field = value_field
|
||||||
|
|
||||||
|
def to_native(self, obj):
|
||||||
|
if obj:
|
||||||
|
return dict(
|
||||||
|
(key, self.value_field.to_native(value) if self.value_field else value)
|
||||||
|
for key, value in obj.items()
|
||||||
|
)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def from_native(self, data):
|
||||||
|
if data:
|
||||||
|
return dict(
|
||||||
|
(
|
||||||
|
unicode(key),
|
||||||
|
field_or_serializer_from_native(self.value_field, value)
|
||||||
|
if self.value_field else value
|
||||||
|
)
|
||||||
|
for key, value in data.items()
|
||||||
|
)
|
||||||
|
return data
|
|
@ -1012,78 +1012,3 @@ class SerializerMethodField(Field):
|
||||||
def field_to_native(self, obj, field_name):
|
def field_to_native(self, obj, field_name):
|
||||||
value = getattr(self.parent, self.method_name)(obj)
|
value = getattr(self.parent, self.method_name)(obj)
|
||||||
return self.to_native(value)
|
return self.to_native(value)
|
||||||
|
|
||||||
|
|
||||||
##### Compound Typed Fields #####
|
|
||||||
|
|
||||||
|
|
||||||
class ListField(WritableField):
|
|
||||||
"""
|
|
||||||
A field whose values are lists of items described by the given item field. The item field can
|
|
||||||
be another field type (e.g., CharField) or a serializer.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, item_field, *args, **kwargs):
|
|
||||||
super(ListField, self).__init__(*args, **kwargs)
|
|
||||||
self.item_field = item_field
|
|
||||||
|
|
||||||
def to_native(self, obj):
|
|
||||||
if obj:
|
|
||||||
return [
|
|
||||||
self.item_field.to_native(item)
|
|
||||||
for item in obj
|
|
||||||
]
|
|
||||||
|
|
||||||
def from_native(self, data):
|
|
||||||
if data:
|
|
||||||
return [
|
|
||||||
self.item_field.from_native(item_data)
|
|
||||||
for item_data in data
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class ListOrObjectField(WritableField):
|
|
||||||
"""
|
|
||||||
A field whose values are either objects or lists of items described by the given item field.
|
|
||||||
The item field can be another field type (e.g., CharField) or a serializer.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, item_field, *args, **kwargs):
|
|
||||||
super(ListOrObjectField, self).__init__(*args, **kwargs)
|
|
||||||
self.item_field = item_field
|
|
||||||
self.list_field = ListField(item_field)
|
|
||||||
|
|
||||||
def to_native(self, obj):
|
|
||||||
if isinstance(obj, list):
|
|
||||||
return self.list_field.to_native(obj)
|
|
||||||
return self.item_field.to_native(obj)
|
|
||||||
|
|
||||||
def from_native(self, data):
|
|
||||||
if isinstance(obj, list):
|
|
||||||
return self.list_field.from_native(obj)
|
|
||||||
return self.item_field.from_native(obj)
|
|
||||||
|
|
||||||
|
|
||||||
class DictField(WritableField):
|
|
||||||
"""
|
|
||||||
A field whose values are dicts of values described by the given value field. The value field
|
|
||||||
can be another field type (e.g., CharField) or a serializer.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, value_field, *args, **kwargs):
|
|
||||||
super(DictField, self).__init__(*args, **kwargs)
|
|
||||||
self.value_field = value_field
|
|
||||||
|
|
||||||
def to_native(self, obj):
|
|
||||||
if obj:
|
|
||||||
return {
|
|
||||||
key:self.value_field.to_native(value)
|
|
||||||
for key, value in obj.items()
|
|
||||||
}
|
|
||||||
|
|
||||||
def from_native(self, data):
|
|
||||||
if data:
|
|
||||||
return {
|
|
||||||
key:self.value_field.from_native(value)
|
|
||||||
for key, value in data.items()
|
|
||||||
}
|
|
||||||
|
|
|
@ -331,7 +331,7 @@ class BaseSerializer(WritableField):
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def from_native(self, data, files=None):
|
def from_native(self, data, files):
|
||||||
"""
|
"""
|
||||||
Deserialize primitives -> objects.
|
Deserialize primitives -> objects.
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue
Block a user