mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-08 06:14:47 +03:00
Merge 42dca62e77
into 5bb02cc7b9
This commit is contained in:
commit
ebdf5222ff
|
@ -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.
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user