This commit is contained in:
Anton Shutik 2015-07-01 12:22:44 +00:00
commit ebdf5222ff
3 changed files with 73 additions and 0 deletions

View File

@ -364,6 +364,18 @@ As with `ChoiceField`, both the `allow_blank` and `allow_null` options are valid
--- ---
# Mapping field
## MappingField
A field that converts value with given mapping dict.
**Signature:** `MappingField(mapping)`
- `mapping` - A dict of valid values that should be converted both directions.
---
# File upload fields # File upload fields
#### Parsers and file uploads. #### Parsers and file uploads.

View File

@ -1165,6 +1165,35 @@ class MultipleChoiceField(ChoiceField):
]) ])
# Mapping types...
class MappingField(Field):
default_error_messages = {
'key_not_found': _('"{value}" not found in "mapping" keys'),
'value_not_found': _('"{value}" not found in "mapping" values')
}
def __init__(self, mapping, **kwargs):
super(MappingField, self).__init__(**kwargs)
assert isinstance(mapping, dict), '"mapping" should be a dictionary'
for k, v in mapping.items():
assert isinstance(k, (str, int)) and isinstance(v, (str, int)), '"mapping" can contain only str or int'
self.mapping = mapping
self.reverse_mapping = {v: k for k, v in mapping.iteritems()}
def to_representation(self, value):
if value in self.mapping:
return self.mapping[value]
self.fail('key_not_found', value=value)
def to_internal_value(self, data):
if data in self.reverse_mapping:
return self.reverse_mapping[data]
self.fail('value_not_found', value=data)
# File types... # File types...
class FileField(Field): class FileField(Field):

View File

@ -1125,6 +1125,38 @@ class TestMultipleChoiceField(FieldValues):
assert field.get_value(QueryDict({})) == rest_framework.fields.empty assert field.get_value(QueryDict({})) == rest_framework.fields.empty
# Mapping types...
class TestMappingFieldWithIntKeys(FieldValues):
"""
Valid and invalid values for `MappingField`.
"""
valid_inputs = {
'one': 1,
'two': 2,
3: 'three',
4: 'four'
}
invalid_inputs = {
5: ['"5" not found in "mapping" values'],
'abc': ['"abc" not found in "mapping" values']
}
outputs = {
1: 'one',
2: 'two',
'three': 3,
'four': 4
}
field = serializers.MappingField(
mapping={
1: 'one',
2: 'two',
'three': 3,
'four': 4
}
)
# File serializers... # File serializers...
class MockFile: class MockFile: