Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
django-rest-framework
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
django-rest-framework
Commits
a1deb5ea
Commit
a1deb5ea
authored
May 23, 2013
by
Oscar Vilaplana
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
simplified, moved field humanizing to Field. broken tests
parent
dea0b6ab
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
56 additions
and
130 deletions
+56
-130
rest_framework/fields.py
+13
-73
rest_framework/serializers.py
+7
-0
rest_framework/tests/fields.py
+35
-56
rest_framework/views.py
+1
-1
No files found.
rest_framework/fields.py
View file @
a1deb5ea
...
...
@@ -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
):
"""
...
...
rest_framework/serializers.py
View file @
a1deb5ea
...
...
@@ -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
...
...
rest_framework/tests/fields.py
View file @
a1deb5ea
...
...
@@ -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
=
TimestampedModel
Serializer
()
self
.
serializer
=
Humanizable
Serializer
()
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
])
rest_framework/views.py
View file @
a1deb5ea
...
...
@@ -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
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment