diff options
| author | Oscar Vilaplana | 2013-05-23 08:26:55 +0200 |
|---|---|---|
| committer | Oscar Vilaplana | 2013-05-23 08:26:55 +0200 |
| commit | a1deb5eac7d6d00c6269d88fce1cc6818d8ec04a (patch) | |
| tree | 2be93e2cd91707f99e409211073ecced428a6d27 | |
| parent | dea0b6ab7fcf8eb9ffebbe7720e4923df7f3c5a4 (diff) | |
| download | django-rest-framework-a1deb5eac7d6d00c6269d88fce1cc6818d8ec04a.tar.bz2 | |
simplified, moved field humanizing to Field. broken tests
| -rw-r--r-- | rest_framework/fields.py | 86 | ||||
| -rw-r--r-- | rest_framework/serializers.py | 7 | ||||
| -rw-r--r-- | rest_framework/tests/fields.py | 91 | ||||
| -rw-r--r-- | rest_framework/views.py | 2 |
4 files changed, 56 insertions, 130 deletions
diff --git a/rest_framework/fields.py b/rest_framework/fields.py index cdcb0ee9..d5a1394d 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -31,36 +31,6 @@ from rest_framework.compat import smart_text, force_text, is_non_str_iterable from rest_framework.settings import api_settings -HUMANIZED_FIELD_TYPES = { - 'BooleanField': u'Boolean', - 'CharField': u'String', - 'ChoiceField': u'Single Choice', - 'ComboField': u'Single Choice', - 'DateField': u'Date', - 'DateTimeField': u'Date and Time', - 'DecimalField': u'Decimal', - 'EmailField': u'Email', - 'Field': u'Field', - 'FileField': u'File', - 'FilePathField': u'File Path', - 'FloatField': u'Float', - 'GenericIPAddressField': u'Generic IP Address', - 'IPAddressField': u'IP Address', - 'ImageField': u'Image', - 'IntegerField': u'Integer', - 'MultiValueField': u'Multiple Value', - 'MultipleChoiceField': u'Multiple Choice', - 'NullBooleanField': u'Nullable Boolean', - 'RegexField': u'Regular Expression', - 'SlugField': u'Slug', - 'SplitDateTimeField': u'Split Date and Time', - 'TimeField': u'Time', - 'TypedChoiceField': u'Typed Single Choice', - 'TypedMultipleChoiceField': u'Typed Multiple Choice', - 'URLField': u'URL', -} - - def is_simple_callable(obj): """ True if the object is a callable that takes no arguments. @@ -102,49 +72,6 @@ def readable_date_formats(formats): return humanize_strptime(format) -def humanize_field_type(field_type): - """Return a human-readable name for a field type. - - :param field_type: Either a field type class (for example - django.forms.fields.DateTimeField), or the name of a field type - (for example "DateTimeField"). - - :return: unicode - - """ - if isinstance(field_type, basestring): - field_type_name = field_type - else: - field_type_name = field_type.__name__ - try: - return HUMANIZED_FIELD_TYPES[field_type_name] - except KeyError: - humanized = re.sub('([a-z0-9])([A-Z])', r'\1 \2', field_type_name) - return humanized.capitalize() - - -def humanize_field(field): - """Return a human-readable description of a field. - - :param field: A Django field. - - :return: A dictionary of the form {type: type name, required: bool, - label: field label: read_only: bool, - help_text: optional help text} - - """ - humanized = { - 'type': humanize_field_type(field.__class__), - 'required': getattr(field, 'required', False), - } - optional_attrs = ['read_only', 'help_text', 'label', - 'min_length', 'max_length'] - for attr in optional_attrs: - if getattr(field, attr, None) is not None: - humanized[attr] = getattr(field, attr) - return humanized - - def humanize_form_fields(form): """Return a humanized description of all the fields in a form. @@ -274,6 +201,19 @@ class Field(object): return {'type': self.type_name} return {} + @property + def humanized(self): + humanized = { + 'type': self.type_name, + 'required': getattr(self, 'required', False), + } + optional_attrs = ['read_only', 'help_text', 'label', + 'min_length', 'max_length'] + for attr in optional_attrs: + if getattr(self, attr, None) is not None: + humanized[attr] = getattr(self, attr) + return humanized + class WritableField(Field): """ diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 943fba6b..072815df 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -521,6 +521,13 @@ class BaseSerializer(WritableField): return self.object + @property + def humanized(self): + humanized_fields = SortedDict( + [(name, field.humanized) + for name, field in self.fields.iteritems()]) + return humanized_fields + class Serializer(six.with_metaclass(SerializerMetaclass, BaseSerializer)): pass diff --git a/rest_framework/tests/fields.py b/rest_framework/tests/fields.py index 85698092..fd1fe961 100644 --- a/rest_framework/tests/fields.py +++ b/rest_framework/tests/fields.py @@ -15,8 +15,7 @@ from django.test import TestCase from django.utils.datastructures import SortedDict from rest_framework import serializers -from rest_framework.fields import (humanize_field, humanize_field_type, - humanize_form_fields, Field) +from rest_framework.fields import Field, CharField from rest_framework.serializers import Serializer from rest_framework.tests.models import RESTFrameworkModel @@ -768,14 +767,16 @@ class SlugFieldTests(TestCase): def test_given_serializer_value(self): class SlugFieldSerializer(serializers.ModelSerializer): - slug_field = serializers.SlugField(source='slug_field', max_length=20, required=False) + slug_field = serializers.SlugField(source='slug_field', + max_length=20, required=False) class Meta: model = self.SlugFieldModel serializer = SlugFieldSerializer(data={}) self.assertEqual(serializer.is_valid(), True) - self.assertEqual(getattr(serializer.fields['slug_field'], 'max_length'), 20) + self.assertEqual(getattr(serializer.fields['slug_field'], + 'max_length'), 20) class URLFieldTests(TestCase): @@ -796,7 +797,8 @@ class URLFieldTests(TestCase): serializer = URLFieldSerializer(data={}) self.assertEqual(serializer.is_valid(), True) - self.assertEqual(getattr(serializer.fields['url_field'], 'max_length'), 200) + self.assertEqual(getattr(serializer.fields['url_field'], + 'max_length'), 200) def test_given_model_value(self): class URLFieldSerializer(serializers.ModelSerializer): @@ -805,48 +807,21 @@ class URLFieldTests(TestCase): serializer = URLFieldSerializer(data={}) self.assertEqual(serializer.is_valid(), True) - self.assertEqual(getattr(serializer.fields['url_field'], 'max_length'), 128) + self.assertEqual(getattr(serializer.fields['url_field'], + 'max_length'), 128) def test_given_serializer_value(self): class URLFieldSerializer(serializers.ModelSerializer): - url_field = serializers.URLField(source='url_field', max_length=20, required=False) + url_field = serializers.URLField(source='url_field', + max_length=20, required=False) class Meta: model = self.URLFieldWithGivenMaxLengthModel serializer = URLFieldSerializer(data={}) self.assertEqual(serializer.is_valid(), True) - self.assertEqual(getattr(serializer.fields['url_field'], 'max_length'), 20) - - -class HumanizedFieldType(TestCase): - def test_standard_type_classes(self): - for field_type_name in forms.fields.__all__: - field_type = getattr(forms.fields, field_type_name) - humanized = humanize_field_type(field_type) - self.assert_valid_name(humanized) - - def test_standard_type_names(self): - for field_type_name in forms.fields.__all__: - humanized = humanize_field_type(field_type_name) - self.assert_valid_name(humanized) - - def test_custom_type_name(self): - humanized = humanize_field_type('SomeCustomType') - self.assertEquals(humanized, u'Some custom type') - - def test_custom_type(self): - custom_type = namedtuple('SomeCustomType', []) - humanized = humanize_field_type(custom_type) - self.assertEquals(humanized, u'Some custom type') - - def assert_valid_name(self, humanized): - """A humanized field name is valid if it's a non-empty - unicode. - - """ - self.assertIsInstance(humanized, unicode) - self.assertNotEqual(humanized, '') + self.assertEqual(getattr(serializer.fields['url_field'], + 'max_length'), 20) class HumanizedField(TestCase): @@ -859,37 +834,41 @@ class HumanizedField(TestCase): self.optional_field.label = uuid4().hex self.optional_field.required = False + def test_type(self): + for field in (self.required_field, self.optional_field): + self.assertEqual(field.humanized['type'], field.type_name) + def test_required(self): - self.assertEqual(humanize_field(self.required_field)['required'], True) + self.assertEqual(self.required_field.humanized['required'], True) def test_optional(self): - self.assertEqual(humanize_field(self.optional_field)['required'], - False) + self.assertEqual(self.optional_field.humanized['required'], False) def test_label(self): for field in (self.required_field, self.optional_field): - self.assertEqual(humanize_field(field)['label'], field.label) + self.assertEqual(field.humanized['label'], field.label) -class Form(forms.Form): - field1 = forms.CharField(max_length=3, label='field one') - field2 = forms.CharField(label='field two') +class HumanizableSerializer(Serializer): + field1 = CharField(3, required=True) + field2 = CharField(10, required=False) class HumanizedSerializer(TestCase): def setUp(self): - self.serializer = TimestampedModelSerializer() + self.serializer = HumanizableSerializer() def test_humanized(self): - humanized = humanize_form_fields(Form()) + humanized = self.serializer.humanized expected = { - 'field1': {u'help_text': u'', - u'label': u'field one', + 'field1': {u'required': True, u'max_length': 3, - u'required': True, - u'type': u'String'}, - 'field2': {u'help_text': u'', - u'label': u'field two', - u'required': True, - u'type': u'String'}} - self.assertEqual(humanized, expected) + u'type': u'CharField', + u'read_only': False}, + 'field2': {u'required': False, + u'max_length': 10, + u'type': u'CharField', + u'read_only': False}} + self.assertEqual(set(expected.keys()), set(humanized.keys())) + for k, v in humanized.iteritems(): + self.assertEqual(v, expected[k]) diff --git a/rest_framework/views.py b/rest_framework/views.py index 5f9e1bf2..d1afbe89 100644 --- a/rest_framework/views.py +++ b/rest_framework/views.py @@ -91,7 +91,7 @@ class APIView(View): continue serializer = self.get_serializer() if serializer is not None: - actions[method] = humanize_form_fields(serializer) + actions[method] = serializer.humanized except exceptions.PermissionDenied: # don't add this method pass |
