mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-03 12:00:12 +03:00
Added tests
This commit is contained in:
parent
e8da3fd9ab
commit
6f250baa06
|
@ -130,6 +130,34 @@ def _is_protected_type(obj):
|
|||
)
|
||||
|
||||
|
||||
def _convert_fields(data, mapping):
|
||||
"""
|
||||
Takes data as dict or none and str->str map of keys and
|
||||
returns None or dictionary with converted keys
|
||||
"""
|
||||
# Handle translation of serialized fields into non serailzed fields
|
||||
if data is not None:
|
||||
translated_data = copy.deepcopy(data)
|
||||
for key in mapping.keys():
|
||||
if key not in translated_data:
|
||||
continue
|
||||
newkey = mapping.get(key)
|
||||
try: # MultiValueDict
|
||||
value = translated_data.getlist(key)
|
||||
del translated_data[key]
|
||||
translated_data.setlist(newkey, value)
|
||||
except AttributeError:
|
||||
value = translated_data.pop(key)
|
||||
translated_data[newkey] = value
|
||||
|
||||
# for key in translated_data.keys():
|
||||
# if key in mapping:
|
||||
else: # Data can be None so translated_data is too
|
||||
translated_data = None
|
||||
|
||||
return translated_data
|
||||
|
||||
|
||||
def _get_declared_fields(bases, attrs):
|
||||
"""
|
||||
Create a list of serializer field instances from the passed in 'attrs',
|
||||
|
@ -166,6 +194,7 @@ class SerializerOptions(object):
|
|||
self.depth = getattr(meta, 'depth', 0)
|
||||
self.fields = getattr(meta, 'fields', ())
|
||||
self.exclude = getattr(meta, 'exclude', ())
|
||||
self.convert_fields = getattr(meta, 'convert_fields', False)
|
||||
|
||||
|
||||
class BaseSerializer(WritableField):
|
||||
|
@ -287,27 +316,14 @@ class BaseSerializer(WritableField):
|
|||
self._errors['non_field_errors'] = ['Invalid data']
|
||||
return None
|
||||
|
||||
# Handle translation of serialized fields into non serailzed fields
|
||||
if data is not None:
|
||||
translated_data = copy.deepcopy(data)
|
||||
field_name_map = self.get_field_name_map()
|
||||
for key in translated_data.keys():
|
||||
if key in field_name_map:
|
||||
newkey = field_name_map.get(key)
|
||||
try: # MultiValueDict
|
||||
value = translated_data.getlist(key)
|
||||
del translated_data[key]
|
||||
translated_data.setlist(newkey, value)
|
||||
except AttributeError:
|
||||
value = translated_data.pop(key)
|
||||
translated_data[newkey] = value
|
||||
else: # Data can be None so translated_data is too
|
||||
translated_data = None
|
||||
if self.opts.convert_fields:
|
||||
key_map = self.get_field_name_map()
|
||||
data = _convert_fields(data, key_map)
|
||||
|
||||
for field_name, field in self.fields.items():
|
||||
field.initialize(parent=self, field_name=field_name)
|
||||
try:
|
||||
field.field_from_native(translated_data, files, field_name, reverted_data)
|
||||
field.field_from_native(data, files, field_name, reverted_data)
|
||||
except ValidationError as err:
|
||||
self._errors[field_name] = list(err.messages)
|
||||
|
||||
|
|
|
@ -175,3 +175,8 @@ class FilterableItem(models.Model):
|
|||
text = models.CharField(max_length=100)
|
||||
decimal = models.DecimalField(max_digits=4, decimal_places=2)
|
||||
date = models.DateField()
|
||||
|
||||
|
||||
class ModelWithUnderscoreFields(RESTFrameworkModel):
|
||||
char_field = models.CharField(max_length=100)
|
||||
number_field = models.IntegerField()
|
||||
|
|
|
@ -7,9 +7,12 @@ from django.utils import unittest
|
|||
from django.utils.datastructures import MultiValueDict
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from rest_framework import serializers, fields, relations
|
||||
from rest_framework.tests.models import (HasPositiveIntegerAsChoice, Album, ActionItem, Anchor, BasicModel,
|
||||
BlankFieldModel, BlogPost, BlogPostComment, Book, CallableDefaultValueModel, DefaultValueModel,
|
||||
ManyToManyModel, Person, ReadOnlyManyToManyModel, Photo, RESTFrameworkModel)
|
||||
from rest_framework.tests.models import (
|
||||
HasPositiveIntegerAsChoice, Album, ActionItem, Anchor, BasicModel,
|
||||
BlankFieldModel, BlogPost, BlogPostComment, Book, CallableDefaultValueModel,
|
||||
DefaultValueModel, ManyToManyModel, Person, ReadOnlyManyToManyModel,
|
||||
Photo, RESTFrameworkModel, ModelWithUnderscoreFields
|
||||
)
|
||||
from rest_framework.tests.models import BasicModelSerializer
|
||||
import datetime
|
||||
import pickle
|
||||
|
@ -176,6 +179,16 @@ class PositiveIntegerAsChoiceSerializer(serializers.ModelSerializer):
|
|||
fields = ['some_integer']
|
||||
|
||||
|
||||
class ModelFieldConversionSerializer(serializers.ModelSerializer):
|
||||
|
||||
def get_field_key(self, field_name):
|
||||
return field_name.replace('_','').capitalize()
|
||||
|
||||
class Meta:
|
||||
convert_fields = True
|
||||
model = ModelWithUnderscoreFields
|
||||
|
||||
|
||||
class BasicTests(TestCase):
|
||||
def setUp(self):
|
||||
self.comment = Comment(
|
||||
|
@ -331,6 +344,23 @@ class BasicTests(TestCase):
|
|||
exclusions = serializer.get_validation_exclusions()
|
||||
self.assertTrue('title' in exclusions, '`title` field was marked `required=False` and should be excluded')
|
||||
|
||||
def test_serialize_with_conversion(self):
|
||||
"""
|
||||
Verify keys get converted from serialized value to deserialized value
|
||||
"""
|
||||
|
||||
underscore = ModelWithUnderscoreFields(char_field='slartibartfast', number_field=42)
|
||||
underscore.save()
|
||||
serializer = ModelFieldConversionSerializer(underscore)
|
||||
serialized = {'Id': 1, 'Numberfield': 42, 'Charfield':'slartibartfast'}
|
||||
self.assertEqual(serialized, serializer.data, "Validate that serialing data with conversion works")
|
||||
|
||||
serializer = ModelFieldConversionSerializer(data=serialized)
|
||||
self.assertTrue(serializer.is_valid(),
|
||||
'Data should get converted from serialized value into deserialized value')
|
||||
self.assertEqual('slartibartfast', serializer.object.char_field)
|
||||
self.assertEqual(42, serializer.object.number_field)
|
||||
|
||||
|
||||
class DictStyleSerializer(serializers.Serializer):
|
||||
"""
|
||||
|
@ -836,6 +866,22 @@ class ManyToManyTests(TestCase):
|
|||
self.assertEqual(instance.pk, 2)
|
||||
self.assertEqual(list(instance.rel.all()), [])
|
||||
|
||||
def test_create_empty_relationship_flat_data_field_convert(self):
|
||||
"""
|
||||
Create an instance of a model with a ManyToMany relationship,
|
||||
containing no items, using a representation that does not support
|
||||
lists (eg form data).
|
||||
"""
|
||||
data = MultiValueDict()
|
||||
data.setlist('rel', [''])
|
||||
self.serializer_class.Meta.convert_fields = True
|
||||
serializer = self.serializer_class(data=data)
|
||||
self.assertEqual(serializer.is_valid(), True)
|
||||
instance = serializer.save()
|
||||
self.assertEqual(len(ManyToManyModel.objects.all()), 2)
|
||||
self.assertEqual(instance.pk, 2)
|
||||
self.assertEqual(list(instance.rel.all()), [])
|
||||
|
||||
|
||||
class ReadOnlyManyToManyTests(TestCase):
|
||||
def setUp(self):
|
||||
|
|
Loading…
Reference in New Issue
Block a user