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
10d386ec
Commit
10d386ec
authored
Aug 23, 2013
by
Tom Christie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Cleanup and dealing with empty form data.
parent
b72a99fe
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
58 additions
and
50 deletions
+58
-50
rest_framework/relations.py
+2
-0
rest_framework/renderers.py
+54
-49
rest_framework/serializers.py
+2
-1
No files found.
rest_framework/relations.py
View file @
10d386ec
...
@@ -244,6 +244,8 @@ class PrimaryKeyRelatedField(RelatedField):
...
@@ -244,6 +244,8 @@ class PrimaryKeyRelatedField(RelatedField):
source
=
self
.
source
or
field_name
source
=
self
.
source
or
field_name
queryset
=
obj
queryset
=
obj
for
component
in
source
.
split
(
'.'
):
for
component
in
source
.
split
(
'.'
):
if
queryset
is
None
:
return
[]
queryset
=
get_component
(
queryset
,
component
)
queryset
=
get_component
(
queryset
,
component
)
# Forward relationship
# Forward relationship
...
...
rest_framework/renderers.py
View file @
10d386ec
...
@@ -319,52 +319,53 @@ class StaticHTMLRenderer(TemplateHTMLRenderer):
...
@@ -319,52 +319,53 @@ class StaticHTMLRenderer(TemplateHTMLRenderer):
class
HTMLFormRenderer
(
BaseRenderer
):
class
HTMLFormRenderer
(
BaseRenderer
):
template
=
'rest_framework/form.html'
template
=
'rest_framework/form.html'
def
serializer_to_form_fields
(
self
,
serializer
):
def
data_to_form_fields
(
self
,
data
):
fields
=
{}
fields
=
{}
for
k
,
v
in
serializer
.
get_fields
()
.
items
():
for
k
ey
,
val
in
data
.
fields
.
items
():
if
getattr
(
v
,
'read_only'
,
True
):
if
getattr
(
v
al
,
'read_only'
,
True
):
continue
continue
kwargs
=
{}
kwargs
=
{}
kwargs
[
'required'
]
=
v
.
required
kwargs
[
'required'
]
=
v
al
.
required
#if getattr(v, 'queryset', None):
#if getattr(v, 'queryset', None):
# kwargs['queryset'] = v.queryset
# kwargs['queryset'] = v.queryset
if
getattr
(
v
,
'choices'
,
None
)
is
not
None
:
if
getattr
(
v
al
,
'choices'
,
None
)
is
not
None
:
kwargs
[
'choices'
]
=
v
.
choices
kwargs
[
'choices'
]
=
v
al
.
choices
if
getattr
(
v
,
'regex'
,
None
)
is
not
None
:
if
getattr
(
v
al
,
'regex'
,
None
)
is
not
None
:
kwargs
[
'regex'
]
=
v
.
regex
kwargs
[
'regex'
]
=
v
al
.
regex
if
getattr
(
v
,
'widget'
,
None
):
if
getattr
(
v
al
,
'widget'
,
None
):
widget
=
copy
.
deepcopy
(
v
.
widget
)
widget
=
copy
.
deepcopy
(
v
al
.
widget
)
kwargs
[
'widget'
]
=
widget
kwargs
[
'widget'
]
=
widget
if
getattr
(
v
,
'default'
,
None
)
is
not
None
:
if
getattr
(
v
al
,
'default'
,
None
)
is
not
None
:
kwargs
[
'initial'
]
=
v
.
default
kwargs
[
'initial'
]
=
v
al
.
default
if
getattr
(
v
,
'label'
,
None
)
is
not
None
:
if
getattr
(
v
al
,
'label'
,
None
)
is
not
None
:
kwargs
[
'label'
]
=
v
.
label
kwargs
[
'label'
]
=
v
al
.
label
if
getattr
(
v
,
'help_text'
,
None
)
is
not
None
:
if
getattr
(
v
al
,
'help_text'
,
None
)
is
not
None
:
kwargs
[
'help_text'
]
=
v
.
help_text
kwargs
[
'help_text'
]
=
v
al
.
help_text
fields
[
k
]
=
v
.
form_field_class
(
**
kwargs
)
fields
[
k
ey
]
=
val
.
form_field_class
(
**
kwargs
)
return
fields
return
fields
def
render
(
self
,
serializer
,
obj
,
request
):
def
render
(
self
,
data
,
accepted_media_type
=
None
,
renderer_context
=
None
):
fields
=
self
.
serializer_to_form_fields
(
serializer
)
self
.
renderer_context
=
renderer_context
or
{}
request
=
renderer_context
[
'request'
]
# Creating an on the fly form see:
# Creating an on the fly form see:
# http://stackoverflow.com/questions/3915024/dynamically-creating-classes-python
# http://stackoverflow.com/questions/3915024/dynamically-creating-classes-python
OnTheFlyForm
=
type
(
str
(
"OnTheFlyForm"
),
(
forms
.
Form
,),
fields
)
fields
=
self
.
data_to_form_fields
(
data
)
data
=
(
obj
is
not
None
)
and
serializer
.
data
or
None
DynamicForm
=
type
(
str
(
'DynamicForm'
),
(
forms
.
Form
,),
fields
)
form_instance
=
OnTheFlyForm
(
data
)
data
=
None
if
data
.
empty
else
data
template
=
loader
.
get_template
(
self
.
template
)
template
=
loader
.
get_template
(
self
.
template
)
context
=
RequestContext
(
request
,
{
'form'
:
form_instance
})
context
=
RequestContext
(
request
,
{
'form'
:
DynamicForm
(
data
)
})
return
template
.
render
(
context
)
return
template
.
render
(
context
)
...
@@ -377,6 +378,7 @@ class BrowsableAPIRenderer(BaseRenderer):
...
@@ -377,6 +378,7 @@ class BrowsableAPIRenderer(BaseRenderer):
format
=
'api'
format
=
'api'
template
=
'rest_framework/api.html'
template
=
'rest_framework/api.html'
charset
=
'utf-8'
charset
=
'utf-8'
form_renderer_class
=
HTMLFormRenderer
def
get_default_renderer
(
self
,
view
):
def
get_default_renderer
(
self
,
view
):
"""
"""
...
@@ -424,19 +426,7 @@ class BrowsableAPIRenderer(BaseRenderer):
...
@@ -424,19 +426,7 @@ class BrowsableAPIRenderer(BaseRenderer):
return
False
# Doesn't have permissions
return
False
# Doesn't have permissions
return
True
return
True
def
_get_form
(
self
,
view
,
method
,
request
):
def
_get_rendered_html_form
(
self
,
view
,
method
,
request
):
# We need to impersonate a request with the correct method,
# so that eg. any dynamic get_serializer_class methods return the
# correct form for each method.
restore
=
view
.
request
request
=
clone_request
(
request
,
method
)
view
.
request
=
request
try
:
return
self
.
get_form
(
view
,
method
,
request
)
finally
:
view
.
request
=
restore
def
_get_raw_data_form
(
self
,
view
,
method
,
request
,
media_types
):
# We need to impersonate a request with the correct method,
# We need to impersonate a request with the correct method,
# so that eg. any dynamic get_serializer_class methods return the
# so that eg. any dynamic get_serializer_class methods return the
# correct form for each method.
# correct form for each method.
...
@@ -444,15 +434,16 @@ class BrowsableAPIRenderer(BaseRenderer):
...
@@ -444,15 +434,16 @@ class BrowsableAPIRenderer(BaseRenderer):
request
=
clone_request
(
request
,
method
)
request
=
clone_request
(
request
,
method
)
view
.
request
=
request
view
.
request
=
request
try
:
try
:
return
self
.
get_r
aw_data_form
(
view
,
method
,
request
,
media_types
)
return
self
.
get_r
endered_html_form
(
view
,
method
,
request
)
finally
:
finally
:
view
.
request
=
restore
view
.
request
=
restore
def
get_form
(
self
,
view
,
method
,
request
):
def
get_
rendered_html_
form
(
self
,
view
,
method
,
request
):
"""
"""
Get a form, possibly bound to either the input or output data.
Return a string representing a rendered HTML form, possibly bound to
In the absence on of the Resource having an associated form then
either the input or output data.
provide a form that can be used to submit arbitrary content.
In the absence of the View having an associated form then return None.
"""
"""
obj
=
getattr
(
view
,
'object'
,
None
)
obj
=
getattr
(
view
,
'object'
,
None
)
if
not
self
.
show_form_for_method
(
view
,
method
,
request
,
obj
):
if
not
self
.
show_form_for_method
(
view
,
method
,
request
,
obj
):
...
@@ -465,7 +456,21 @@ class BrowsableAPIRenderer(BaseRenderer):
...
@@ -465,7 +456,21 @@ class BrowsableAPIRenderer(BaseRenderer):
return
return
serializer
=
view
.
get_serializer
(
instance
=
obj
)
serializer
=
view
.
get_serializer
(
instance
=
obj
)
return
HTMLFormRenderer
()
.
render
(
serializer
,
obj
,
request
)
data
=
serializer
.
data
form_renderer
=
self
.
form_renderer_class
()
return
form_renderer
.
render
(
data
,
self
.
accepted_media_type
,
self
.
renderer_context
)
def
_get_raw_data_form
(
self
,
view
,
method
,
request
,
media_types
):
# We need to impersonate a request with the correct method,
# so that eg. any dynamic get_serializer_class methods return the
# correct form for each method.
restore
=
view
.
request
request
=
clone_request
(
request
,
method
)
view
.
request
=
request
try
:
return
self
.
get_raw_data_form
(
view
,
method
,
request
,
media_types
)
finally
:
view
.
request
=
restore
def
get_raw_data_form
(
self
,
view
,
method
,
request
,
media_types
):
def
get_raw_data_form
(
self
,
view
,
method
,
request
,
media_types
):
"""
"""
...
@@ -520,8 +525,8 @@ class BrowsableAPIRenderer(BaseRenderer):
...
@@ -520,8 +525,8 @@ class BrowsableAPIRenderer(BaseRenderer):
"""
"""
Render the HTML for the browsable API representation.
Render the HTML for the browsable API representation.
"""
"""
accepted_media_type
=
accepted_media_type
or
''
self
.
accepted_media_type
=
accepted_media_type
or
''
renderer_context
=
renderer_context
or
{}
self
.
renderer_context
=
renderer_context
or
{}
view
=
renderer_context
[
'view'
]
view
=
renderer_context
[
'view'
]
request
=
renderer_context
[
'request'
]
request
=
renderer_context
[
'request'
]
...
@@ -531,11 +536,11 @@ class BrowsableAPIRenderer(BaseRenderer):
...
@@ -531,11 +536,11 @@ class BrowsableAPIRenderer(BaseRenderer):
renderer
=
self
.
get_default_renderer
(
view
)
renderer
=
self
.
get_default_renderer
(
view
)
content
=
self
.
get_content
(
renderer
,
data
,
accepted_media_type
,
renderer_context
)
content
=
self
.
get_content
(
renderer
,
data
,
accepted_media_type
,
renderer_context
)
put_form
=
self
.
_get_form
(
view
,
'PUT'
,
request
)
put_form
=
self
.
_get_
rendered_html_
form
(
view
,
'PUT'
,
request
)
post_form
=
self
.
_get_form
(
view
,
'POST'
,
request
)
post_form
=
self
.
_get_
rendered_html_
form
(
view
,
'POST'
,
request
)
patch_form
=
self
.
_get_form
(
view
,
'PATCH'
,
request
)
patch_form
=
self
.
_get_
rendered_html_
form
(
view
,
'PATCH'
,
request
)
delete_form
=
self
.
_get_form
(
view
,
'DELETE'
,
request
)
delete_form
=
self
.
_get_
rendered_html_
form
(
view
,
'DELETE'
,
request
)
options_form
=
self
.
_get_form
(
view
,
'OPTIONS'
,
request
)
options_form
=
self
.
_get_
rendered_html_
form
(
view
,
'OPTIONS'
,
request
)
raw_data_put_form
=
self
.
_get_raw_data_form
(
view
,
'PUT'
,
request
,
media_types
)
raw_data_put_form
=
self
.
_get_raw_data_form
(
view
,
'PUT'
,
request
,
media_types
)
raw_data_post_form
=
self
.
_get_raw_data_form
(
view
,
'POST'
,
request
,
media_types
)
raw_data_post_form
=
self
.
_get_raw_data_form
(
view
,
'POST'
,
request
,
media_types
)
...
...
rest_framework/serializers.py
View file @
10d386ec
...
@@ -300,7 +300,8 @@ class BaseSerializer(WritableField):
...
@@ -300,7 +300,8 @@ class BaseSerializer(WritableField):
Serialize objects -> primitives.
Serialize objects -> primitives.
"""
"""
ret
=
self
.
_dict_class
()
ret
=
self
.
_dict_class
()
ret
.
fields
=
{}
ret
.
fields
=
self
.
_dict_class
()
ret
.
empty
=
obj
is
None
for
field_name
,
field
in
self
.
fields
.
items
():
for
field_name
,
field
in
self
.
fields
.
items
():
field
.
initialize
(
parent
=
self
,
field_name
=
field_name
)
field
.
initialize
(
parent
=
self
,
field_name
=
field_name
)
...
...
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