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
4dffcb5d
Commit
4dffcb5d
authored
May 18, 2013
by
Oscar Vilaplana
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added humanized field names and types
parent
29739f78
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
148 additions
and
2 deletions
+148
-2
rest_framework/fields.py
+89
-2
rest_framework/tests/fields.py
+57
-0
rest_framework/views.py
+2
-0
No files found.
rest_framework/fields.py
View file @
4dffcb5d
...
@@ -23,13 +23,44 @@ from django.utils.translation import ugettext_lazy as _
...
@@ -23,13 +23,44 @@ from django.utils.translation import ugettext_lazy as _
from
django.utils.datastructures
import
SortedDict
from
django.utils.datastructures
import
SortedDict
from
rest_framework
import
ISO_8601
from
rest_framework
import
ISO_8601
from
rest_framework.compat
import
timezone
,
parse_date
,
parse_datetime
,
parse_time
from
rest_framework.compat
import
(
timezone
,
parse_date
,
parse_datetime
,
parse_time
)
from
rest_framework.compat
import
BytesIO
from
rest_framework.compat
import
BytesIO
from
rest_framework.compat
import
six
from
rest_framework.compat
import
six
from
rest_framework.compat
import
smart_text
from
rest_framework.compat
import
smart_text
from
rest_framework.settings
import
api_settings
from
rest_framework.settings
import
api_settings
HUMANIZED_FIELD_TYPES
=
{
'BooleanField'
:
u'Boolean'
,
'CharField'
:
u'Single Character'
,
'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
):
def
is_simple_callable
(
obj
):
"""
"""
True if the object is a callable that takes no arguments.
True if the object is a callable that takes no arguments.
...
@@ -62,7 +93,8 @@ def get_component(obj, attr_name):
...
@@ -62,7 +93,8 @@ def get_component(obj, attr_name):
def
readable_datetime_formats
(
formats
):
def
readable_datetime_formats
(
formats
):
format
=
', '
.
join
(
formats
)
.
replace
(
ISO_8601
,
'YYYY-MM-DDThh:mm[:ss[.uuuuuu]][+HHMM|-HHMM|Z]'
)
format
=
', '
.
join
(
formats
)
.
replace
(
ISO_8601
,
'YYYY-MM-DDThh:mm[:ss[.uuuuuu]][+HHMM|-HHMM|Z]'
)
return
humanize_strptime
(
format
)
return
humanize_strptime
(
format
)
...
@@ -71,6 +103,61 @@ def readable_date_formats(formats):
...
@@ -71,6 +103,61 @@ def readable_date_formats(formats):
return
humanize_strptime
(
format
)
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'
:
(
field
.
type_name
if
field
.
type_name
else
humanize_field_type
(
field
.
form_field_class
)),
'required'
:
getattr
(
field
,
'required'
,
False
),
'label'
:
field
.
label
,
}
optional_attrs
=
[
'read_only'
,
'help_text'
]
for
attr
in
optional_attrs
:
if
hasattr
(
field
,
attr
):
humanized
[
attr
]
=
getattr
(
field
,
attr
)
return
humanized
def
humanize_form_fields
(
form
):
"""Return a humanized description of all the fields in a form.
:param form: A Django form.
:return: A dictionary of {field_label: humanized description}
"""
fields
=
SortedDict
([(
f
.
name
,
humanize_field
(
f
))
for
f
in
form
.
fields
])
return
fields
def
readable_time_formats
(
formats
):
def
readable_time_formats
(
formats
):
format
=
', '
.
join
(
formats
)
.
replace
(
ISO_8601
,
'hh:mm[:ss[.uuuuuu]]'
)
format
=
', '
.
join
(
formats
)
.
replace
(
ISO_8601
,
'hh:mm[:ss[.uuuuuu]]'
)
return
humanize_strptime
(
format
)
return
humanize_strptime
(
format
)
...
...
rest_framework/tests/fields.py
View file @
4dffcb5d
...
@@ -4,12 +4,17 @@ General serializer field tests.
...
@@ -4,12 +4,17 @@ General serializer field tests.
from
__future__
import
unicode_literals
from
__future__
import
unicode_literals
from
django.utils.datastructures
import
SortedDict
from
django.utils.datastructures
import
SortedDict
import
datetime
import
datetime
from
rest_framework.fields
import
humanize_field
,
humanize_field_type
from
django
import
forms
from
decimal
import
Decimal
from
decimal
import
Decimal
from
django.db
import
models
from
django.db
import
models
from
django.test
import
TestCase
from
django.test
import
TestCase
from
django.core
import
validators
from
django.core
import
validators
from
rest_framework
import
serializers
from
rest_framework
import
serializers
from
rest_framework.serializers
import
Serializer
from
rest_framework.serializers
import
Serializer
from
rest_framework.fields
import
Field
from
collections
import
namedtuple
from
uuid
import
uuid4
class
TimestampedModel
(
models
.
Model
):
class
TimestampedModel
(
models
.
Model
):
...
@@ -685,3 +690,55 @@ class ChoiceFieldTests(TestCase):
...
@@ -685,3 +690,55 @@ class ChoiceFieldTests(TestCase):
"""
"""
f
=
serializers
.
ChoiceField
(
required
=
False
,
choices
=
self
.
SAMPLE_CHOICES
)
f
=
serializers
.
ChoiceField
(
required
=
False
,
choices
=
self
.
SAMPLE_CHOICES
)
self
.
assertEqual
(
f
.
choices
,
models
.
fields
.
BLANK_CHOICE_DASH
+
self
.
SAMPLE_CHOICES
)
self
.
assertEqual
(
f
.
choices
,
models
.
fields
.
BLANK_CHOICE_DASH
+
self
.
SAMPLE_CHOICES
)
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
.
assertTrue
(
humanized
)
class
HumanizedField
(
TestCase
):
def
setUp
(
self
):
self
.
required_field
=
Field
()
self
.
required_field
.
label
=
uuid4
()
.
hex
self
.
required_field
.
required
=
True
self
.
optional_field
=
Field
()
self
.
optional_field
.
label
=
uuid4
()
.
hex
self
.
optional_field
.
required
=
False
def
test_required
(
self
):
self
.
assertEqual
(
humanize_field
(
self
.
required_field
)[
'required'
],
True
)
def
test_optional
(
self
):
self
.
assertEqual
(
humanize_field
(
self
.
optional_field
)[
'required'
],
False
)
def
test_label
(
self
):
for
field
in
(
self
.
required_field
,
self
.
optional_field
):
self
.
assertEqual
(
humanize_field
(
field
)[
'label'
],
field
.
label
)
rest_framework/views.py
View file @
4dffcb5d
...
@@ -80,6 +80,8 @@ class APIView(View):
...
@@ -80,6 +80,8 @@ class APIView(View):
if
serializer
is
not
None
:
if
serializer
is
not
None
:
field_name_types
=
{}
field_name_types
=
{}
for
name
,
field
in
serializer
.
fields
.
iteritems
():
for
name
,
field
in
serializer
.
fields
.
iteritems
():
from
rest_framework.fields
import
humanize_field
humanize_field
(
field
)
field_name_types
[
name
]
=
field
.
__class__
.
__name__
field_name_types
[
name
]
=
field
.
__class__
.
__name__
actions
[
method
]
=
field_name_types
actions
[
method
]
=
field_name_types
...
...
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