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
37e2720a
Commit
37e2720a
authored
Aug 29, 2013
by
Tom Christie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add `override_method` context manager and cleanup.
parent
18007d68
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
36 additions
and
62 deletions
+36
-62
rest_framework/renderers.py
+13
-62
rest_framework/request.py
+23
-0
No files found.
rest_framework/renderers.py
View file @
37e2720a
...
...
@@ -21,7 +21,7 @@ from rest_framework.compat import six
from
rest_framework.compat
import
smart_text
from
rest_framework.compat
import
yaml
from
rest_framework.settings
import
api_settings
from
rest_framework.request
import
clone_request
,
is_form_media_type
from
rest_framework.request
import
is_form_media_type
,
override_method
from
rest_framework.utils
import
encoders
from
rest_framework.utils.breadcrumbs
import
get_breadcrumbs
from
rest_framework
import
exceptions
,
status
,
VERSION
...
...
@@ -456,18 +456,6 @@ class BrowsableAPIRenderer(BaseRenderer):
return
False
# Doesn't have permissions
return
True
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_rendered_html_form
(
view
,
method
,
request
)
finally
:
view
.
request
=
restore
def
get_rendered_html_form
(
self
,
view
,
method
,
request
):
"""
Return a string representing a rendered HTML form, possibly bound to
...
...
@@ -475,6 +463,7 @@ class BrowsableAPIRenderer(BaseRenderer):
In the absence of the View having an associated form then return None.
"""
with
override_method
(
view
,
request
,
method
)
as
request
:
obj
=
getattr
(
view
,
'object'
,
None
)
if
not
self
.
show_form_for_method
(
view
,
method
,
request
,
obj
):
return
...
...
@@ -482,7 +471,8 @@ class BrowsableAPIRenderer(BaseRenderer):
if
method
in
(
'DELETE'
,
'OPTIONS'
):
return
True
# Don't actually need to return a form
if
not
getattr
(
view
,
'get_serializer'
,
None
)
or
not
any
(
is_form_media_type
(
parser
.
media_type
)
for
parser
in
view
.
parser_classes
):
if
(
not
getattr
(
view
,
'get_serializer'
,
None
)
or
not
any
(
is_form_media_type
(
parser
.
media_type
)
for
parser
in
view
.
parser_classes
)):
return
serializer
=
view
.
get_serializer
(
instance
=
obj
)
...
...
@@ -490,25 +480,13 @@ class BrowsableAPIRenderer(BaseRenderer):
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
):
"""
Returns a form that allows for arbitrary content types to be tunneled
via standard HTML forms.
(Which are typically application/x-www-form-urlencoded)
"""
with
override_method
(
view
,
request
,
method
)
as
request
:
# If we're not using content overloading there's no point in supplying a generic form,
# as the view won't treat the form's value as the content of the request.
if
not
(
api_settings
.
FORM_CONTENT_OVERRIDE
...
...
@@ -562,47 +540,20 @@ class BrowsableAPIRenderer(BaseRenderer):
request
=
renderer_context
[
'request'
]
response
=
renderer_context
[
'response'
]
obj
=
getattr
(
view
,
'object'
,
None
)
if
getattr
(
view
,
'get_serializer'
,
None
):
serializer
=
view
.
get_serializer
(
instance
=
obj
)
for
field_name
,
field
in
serializer
.
fields
.
items
():
if
field
.
read_only
:
del
serializer
.
fields
[
field_name
]
else
:
serializer
=
None
parsers
=
[]
for
parser_class
in
view
.
parser_classes
:
if
is_form_media_type
(
parser_class
.
media_type
):
continue
content
=
None
renderer_class
=
getattr
(
parser_class
,
'renderer_class'
,
None
)
if
renderer_class
and
serializer
:
renderer
=
renderer_class
()
context
=
renderer_context
.
copy
()
context
[
'indent'
]
=
4
content
=
renderer
.
render
(
serializer
.
data
,
accepted_media_type
,
context
)
print
content
parsers
.
append
({
'media_type'
:
parser_class
.
media_type
,
'content'
:
content
})
media_types
=
[
parser
.
media_type
for
parser
in
view
.
parser_classes
]
renderer
=
self
.
get_default_renderer
(
view
)
content
=
self
.
get_content
(
renderer
,
data
,
accepted_media_type
,
renderer_context
)
put_form
=
self
.
_
get_rendered_html_form
(
view
,
'PUT'
,
request
)
post_form
=
self
.
_
get_rendered_html_form
(
view
,
'POST'
,
request
)
patch_form
=
self
.
_
get_rendered_html_form
(
view
,
'PATCH'
,
request
)
delete_form
=
self
.
_
get_rendered_html_form
(
view
,
'DELETE'
,
request
)
options_form
=
self
.
_
get_rendered_html_form
(
view
,
'OPTIONS'
,
request
)
put_form
=
self
.
get_rendered_html_form
(
view
,
'PUT'
,
request
)
post_form
=
self
.
get_rendered_html_form
(
view
,
'POST'
,
request
)
patch_form
=
self
.
get_rendered_html_form
(
view
,
'PATCH'
,
request
)
delete_form
=
self
.
get_rendered_html_form
(
view
,
'DELETE'
,
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_post_form
=
self
.
_
get_raw_data_form
(
view
,
'POST'
,
request
,
media_types
)
raw_data_patch_form
=
self
.
_
get_raw_data_form
(
view
,
'PATCH'
,
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_patch_form
=
self
.
get_raw_data_form
(
view
,
'PATCH'
,
request
,
media_types
)
raw_data_put_or_patch_form
=
raw_data_put_form
or
raw_data_patch_form
name
=
self
.
get_name
(
view
)
...
...
rest_framework/request.py
View file @
37e2720a
...
...
@@ -28,6 +28,29 @@ def is_form_media_type(media_type):
base_media_type
==
'multipart/form-data'
)
class
override_method
(
object
):
"""
A context manager that temporarily overrides the method on a request,
additionally setting the `view.request` attribute.
Usage:
with override_method(view, request, 'POST') as request:
... # Do stuff with `view` and `request`
"""
def
__init__
(
self
,
view
,
request
,
method
):
self
.
view
=
view
self
.
request
=
request
self
.
method
=
method
def
__enter__
(
self
):
self
.
view
.
request
=
clone_request
(
self
.
request
,
self
.
method
)
return
self
.
view
.
request
def
__exit__
(
self
,
*
args
,
**
kwarg
):
self
.
view
.
request
=
self
.
request
class
Empty
(
object
):
"""
Placeholder for unset attributes.
...
...
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