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
44c8b89c
Commit
44c8b89c
authored
May 12, 2011
by
Tom Christie
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
_perform_form_overloading becomes transparent
parent
a31a68d6
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
48 additions
and
91 deletions
+48
-91
djangorestframework/mixins.py
+42
-79
djangorestframework/tests/content.py
+3
-4
djangorestframework/tests/files.py
+2
-2
djangorestframework/tests/methods.py
+0
-1
djangorestframework/views.py
+1
-5
No files found.
djangorestframework/mixins.py
View file @
44c8b89c
...
@@ -54,7 +54,7 @@ class RequestMixin(object):
...
@@ -54,7 +54,7 @@ class RequestMixin(object):
Returns the HTTP method.
Returns the HTTP method.
"""
"""
if
not
hasattr
(
self
,
'_method'
):
if
not
hasattr
(
self
,
'_method'
):
self
.
_load_met
adata
()
self
.
_load_met
hod_and_content_type
()
return
self
.
_method
return
self
.
_method
...
@@ -64,7 +64,7 @@ class RequestMixin(object):
...
@@ -64,7 +64,7 @@ class RequestMixin(object):
Returns the content type header.
Returns the content type header.
"""
"""
if
not
hasattr
(
self
,
'_content_type'
):
if
not
hasattr
(
self
,
'_content_type'
):
self
.
_load_met
adata
()
self
.
_load_met
hod_and_content_type
()
return
self
.
_content_type
return
self
.
_content_type
...
@@ -92,12 +92,16 @@ class RequestMixin(object):
...
@@ -92,12 +92,16 @@ class RequestMixin(object):
"""
"""
Parse the request content into self.DATA and self.FILES.
Parse the request content into self.DATA and self.FILES.
"""
"""
stream
=
self
.
_get_stream
()
if
not
hasattr
(
self
,
'_content_type'
):
(
self
.
_data
,
self
.
_files
)
=
self
.
_parse
(
stream
,
self
.
content_type
)
self
.
_load_method_and_content_type
()
if
not
hasattr
(
self
,
'_data'
):
(
self
.
_data
,
self
.
_files
)
=
self
.
_parse
(
self
.
_get_stream
(),
self
.
_content_type
)
def
_load_metadata
(
self
):
def
_load_method_and_content_type
(
self
):
"""
"""
Set the method and content_type and then check if they've been overridden.
Set the method and content_type
,
and then check if they've been overridden.
"""
"""
self
.
_method
=
self
.
request
.
method
self
.
_method
=
self
.
request
.
method
self
.
_content_type
=
self
.
request
.
META
.
get
(
'HTTP_CONTENT_TYPE'
,
self
.
request
.
META
.
get
(
'CONTENT_TYPE'
,
''
))
self
.
_content_type
=
self
.
request
.
META
.
get
(
'HTTP_CONTENT_TYPE'
,
self
.
request
.
META
.
get
(
'CONTENT_TYPE'
,
''
))
...
@@ -108,86 +112,45 @@ class RequestMixin(object):
...
@@ -108,86 +112,45 @@ class RequestMixin(object):
"""
"""
Returns an object that may be used to stream the request content.
Returns an object that may be used to stream the request content.
"""
"""
if
not
hasattr
(
self
,
'_stream'
):
request
=
self
.
request
request
=
self
.
request
try
:
try
:
content_length
=
int
(
request
.
META
.
get
(
'CONTENT_LENGTH'
,
request
.
META
.
get
(
'HTTP_CONTENT_LENGTH'
)))
content_length
=
int
(
request
.
META
.
get
(
'CONTENT_LENGTH'
,
request
.
META
.
get
(
'HTTP_CONTENT_LENGTH'
)))
except
(
ValueError
,
TypeError
):
except
(
ValueError
,
TypeError
):
content_length
=
0
content_length
=
0
# TODO: Add 1.3's LimitedStream to compat and use that.
# TODO: Add 1.3's LimitedStream to compat and use that.
# Currently only supports parsing request body as a stream with 1.3
# Currently only supports parsing request body as a stream with 1.3
if
content_length
==
0
:
if
content_length
==
0
:
return
None
return
None
elif
hasattr
(
request
,
'read'
):
elif
hasattr
(
request
,
'read'
):
return
request
# UPDATE BASED ON COMMENT BELOW:
return
StringIO
(
request
.
raw_post_data
)
#
# Yup, this was a bug in Django - fixed and waiting check in - see ticket 15785.
# http://code.djangoproject.com/ticket/15785
#
# COMMENT:
#
# It's not at all clear if this needs to be byte limited or not.
# Maybe I'm just being dumb but it looks to me like there's some issues
# with that in Django.
#
# Either:
# 1. It *can't* be treated as a limited byte stream, and you _do_ need to
# respect CONTENT_LENGTH, in which case that ought to be documented,
# and there probably ought to be a feature request for it to be
# treated as a limited byte stream.
# 2. It *can* be treated as a limited byte stream, in which case there's a
# minor bug in the test client, and potentially some redundant
# code in MultiPartParser.
#
# It's an issue because it affects if you can pass a request off to code that
# does something like:
#
# while stream.read(BUFFER_SIZE):
# [do stuff]
#
#try:
# content_length = int(request.META.get('CONTENT_LENGTH',0))
#except (ValueError, TypeError):
# content_length = 0
# self._stream = LimitedStream(request, content_length)
self
.
_stream
=
request
else
:
self
.
_stream
=
StringIO
(
request
.
raw_post_data
)
return
self
.
_stream
# TODO: Modify this so that it happens implictly, rather than being called explicitly
# ie accessing any of .DATA, .FILES, .content_type, .method will force
# form overloading.
def
_perform_form_overloading
(
self
):
def
_perform_form_overloading
(
self
):
"""
"""
Check the request to see if it is using form POST '_method'/'_content'/'_content_type' overrides.
If this is a form POST request, then we need to check if the method and content/content_type have been
If it is then alter self.method, self.content_type, self.CONTENT to reflect that rather than simply
overridden by setting them in hidden form fields or not.
delegating them to the original request.
"""
"""
# We only need to use form overloading on form POST requests
# We only need to use form overloading on form POST requests
.
if
not
self
.
_USE_FORM_OVERLOADING
or
self
.
_method
!=
'POST'
or
not
not
is_form_media_type
(
self
.
_content_type
):
if
not
self
.
_USE_FORM_OVERLOADING
or
self
.
_method
!=
'POST'
or
not
is_form_media_type
(
self
.
_content_type
):
return
return
# Temporarily switch to using the form parsers, then parse the content
# At this point we're committed to parsing the request as form data.
parsers
=
self
.
parsers
self
.
_data
=
data
=
self
.
request
.
POST
self
.
parsers
=
(
FormParser
,
MultiPartParser
)
self
.
_files
=
self
.
request
.
FILES
content
=
self
.
DATA
self
.
parsers
=
parsers
# Method overloading - change the method and remove the param from the content.
if
self
.
_METHOD_PARAM
in
data
:
# Method overloading - change the method and remove the param from the content
self
.
_method
=
data
[
self
.
_METHOD_PARAM
]
.
upper
()
if
self
.
_METHOD_PARAM
in
content
:
self
.
_method
=
content
[
self
.
_METHOD_PARAM
]
.
upper
()
# Content overloading - modify the content type, and re-parse.
del
self
.
_data
[
self
.
_METHOD_PARAM
]
if
self
.
_CONTENT_PARAM
in
data
and
self
.
_CONTENTTYPE_PARAM
in
data
:
self
.
_content_type
=
data
[
self
.
_CONTENTTYPE_PARAM
]
# Content overloading - rewind the stream and modify the content type
stream
=
StringIO
(
data
[
self
.
_CONTENT_PARAM
])
if
self
.
_CONTENT_PARAM
in
content
and
self
.
_CONTENTTYPE_PARAM
in
content
:
(
self
.
_data
,
self
.
_files
)
=
self
.
_parse
(
stream
,
self
.
_content_type
)
self
.
_content_type
=
content
[
self
.
_CONTENTTYPE_PARAM
]
self
.
_stream
=
StringIO
(
content
[
self
.
_CONTENT_PARAM
])
del
(
self
.
_data
)
def
_parse
(
self
,
stream
,
content_type
):
def
_parse
(
self
,
stream
,
content_type
):
...
...
djangorestframework/tests/content.py
View file @
44c8b89c
...
@@ -12,16 +12,16 @@ class TestContentParsing(TestCase):
...
@@ -12,16 +12,16 @@ class TestContentParsing(TestCase):
self
.
req
=
RequestFactory
()
self
.
req
=
RequestFactory
()
def
ensure_determines_no_content_GET
(
self
,
view
):
def
ensure_determines_no_content_GET
(
self
,
view
):
"""Ensure view.
RAW_CONTENT
returns None for GET request with no content."""
"""Ensure view.
DATA
returns None for GET request with no content."""
view
.
request
=
self
.
req
.
get
(
'/'
)
view
.
request
=
self
.
req
.
get
(
'/'
)
self
.
assertEqual
(
view
.
DATA
,
None
)
self
.
assertEqual
(
view
.
DATA
,
None
)
def
ensure_determines_form_content_POST
(
self
,
view
):
def
ensure_determines_form_content_POST
(
self
,
view
):
"""Ensure view.
RAW_CONTENT
returns content for POST request with form content."""
"""Ensure view.
DATA
returns content for POST request with form content."""
form_data
=
{
'qwerty'
:
'uiop'
}
form_data
=
{
'qwerty'
:
'uiop'
}
view
.
parsers
=
(
FormParser
,
MultiPartParser
)
view
.
parsers
=
(
FormParser
,
MultiPartParser
)
view
.
request
=
self
.
req
.
post
(
'/'
,
data
=
form_data
)
view
.
request
=
self
.
req
.
post
(
'/'
,
data
=
form_data
)
self
.
assertEqual
(
view
.
DATA
,
form_data
)
self
.
assertEqual
(
view
.
DATA
.
items
(),
form_data
.
items
()
)
def
ensure_determines_non_form_content_POST
(
self
,
view
):
def
ensure_determines_non_form_content_POST
(
self
,
view
):
"""Ensure view.RAW_CONTENT returns content for POST request with non-form content."""
"""Ensure view.RAW_CONTENT returns content for POST request with non-form content."""
...
@@ -75,5 +75,4 @@ class TestContentParsing(TestCase):
...
@@ -75,5 +75,4 @@ class TestContentParsing(TestCase):
view
.
_CONTENTTYPE_PARAM
:
content_type
}
view
.
_CONTENTTYPE_PARAM
:
content_type
}
view
.
request
=
self
.
req
.
post
(
'/'
,
form_data
)
view
.
request
=
self
.
req
.
post
(
'/'
,
form_data
)
view
.
parsers
=
(
PlainTextParser
,)
view
.
parsers
=
(
PlainTextParser
,)
view
.
_perform_form_overloading
()
self
.
assertEqual
(
view
.
DATA
,
content
)
self
.
assertEqual
(
view
.
DATA
,
content
)
djangorestframework/tests/files.py
View file @
44c8b89c
...
@@ -24,8 +24,8 @@ class UploadFilesTests(TestCase):
...
@@ -24,8 +24,8 @@ class UploadFilesTests(TestCase):
resource
=
MockResource
resource
=
MockResource
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
return
{
'FILE_NAME'
:
self
.
CONTENT
[
'file'
]
.
name
,
return
{
'FILE_NAME'
:
self
.
CONTENT
[
'file'
]
[
0
]
.
name
,
'FILE_CONTENT'
:
self
.
CONTENT
[
'file'
]
.
read
()}
'FILE_CONTENT'
:
self
.
CONTENT
[
'file'
]
[
0
]
.
read
()}
file
=
StringIO
.
StringIO
(
'stuff'
)
file
=
StringIO
.
StringIO
(
'stuff'
)
file
.
name
=
'stuff.txt'
file
.
name
=
'stuff.txt'
...
...
djangorestframework/tests/methods.py
View file @
44c8b89c
...
@@ -23,5 +23,4 @@ class TestMethodOverloading(TestCase):
...
@@ -23,5 +23,4 @@ class TestMethodOverloading(TestCase):
"""POST requests can be overloaded to another method by setting a reserved form field"""
"""POST requests can be overloaded to another method by setting a reserved form field"""
view
=
RequestMixin
()
view
=
RequestMixin
()
view
.
request
=
self
.
req
.
post
(
'/'
,
{
view
.
_METHOD_PARAM
:
'DELETE'
})
view
.
request
=
self
.
req
.
post
(
'/'
,
{
view
.
_METHOD_PARAM
:
'DELETE'
})
view
.
_perform_form_overloading
()
self
.
assertEqual
(
view
.
method
,
'DELETE'
)
self
.
assertEqual
(
view
.
method
,
'DELETE'
)
djangorestframework/views.py
View file @
44c8b89c
...
@@ -77,11 +77,7 @@ class BaseView(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, View):
...
@@ -77,11 +77,7 @@ class BaseView(ResourceMixin, RequestMixin, ResponseMixin, AuthMixin, View):
prefix
=
'
%
s://
%
s'
%
(
request
.
is_secure
()
and
'https'
or
'http'
,
request
.
get_host
())
prefix
=
'
%
s://
%
s'
%
(
request
.
is_secure
()
and
'https'
or
'http'
,
request
.
get_host
())
set_script_prefix
(
prefix
)
set_script_prefix
(
prefix
)
try
:
try
:
# If using a form POST with '_method'/'_content'/'_content_type' overrides, then alter
# self.method, self.content_type, self.RAW_CONTENT & self.CONTENT appropriately.
self
.
_perform_form_overloading
()
# Authenticate and check request is has the relevant permissions
# Authenticate and check request is has the relevant permissions
self
.
_check_permissions
()
self
.
_check_permissions
()
...
...
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