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
be74d111
Commit
be74d111
authored
Sep 21, 2016
by
Tom Christie
Committed by
GitHub
Sep 21, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fallback behavior for request parsing when request.POST already accessed. (#4500)
parent
e82ee910
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
66 additions
and
4 deletions
+66
-4
rest_framework/request.py
+24
-3
tests/test_parsers.py
+42
-1
No files found.
rest_framework/request.py
View file @
be74d111
...
@@ -15,6 +15,7 @@ import sys
...
@@ -15,6 +15,7 @@ import sys
from
django.conf
import
settings
from
django.conf
import
settings
from
django.http
import
QueryDict
from
django.http
import
QueryDict
from
django.http.multipartparser
import
parse_header
from
django.http.multipartparser
import
parse_header
from
django.http.request
import
RawPostDataException
from
django.utils
import
six
from
django.utils
import
six
from
django.utils.datastructures
import
MultiValueDict
from
django.utils.datastructures
import
MultiValueDict
...
@@ -263,10 +264,20 @@ class Request(object):
...
@@ -263,10 +264,20 @@ class Request(object):
if
content_length
==
0
:
if
content_length
==
0
:
self
.
_stream
=
None
self
.
_stream
=
None
elif
hasattr
(
self
.
_request
,
'read'
)
:
elif
not
self
.
_request
.
_read_started
:
self
.
_stream
=
self
.
_request
self
.
_stream
=
self
.
_request
else
:
else
:
self
.
_stream
=
six
.
BytesIO
(
self
.
raw_post_data
)
self
.
_stream
=
six
.
BytesIO
(
self
.
body
)
def
_supports_form_parsing
(
self
):
"""
Return True if this requests supports parsing form data.
"""
form_media
=
(
'application/x-www-form-urlencoded'
,
'multipart/form-data'
)
return
any
([
parser
.
media_type
in
form_media
for
parser
in
self
.
parsers
])
def
_parse
(
self
):
def
_parse
(
self
):
"""
"""
...
@@ -274,8 +285,18 @@ class Request(object):
...
@@ -274,8 +285,18 @@ class Request(object):
May raise an `UnsupportedMediaType`, or `ParseError` exception.
May raise an `UnsupportedMediaType`, or `ParseError` exception.
"""
"""
stream
=
self
.
stream
media_type
=
self
.
content_type
media_type
=
self
.
content_type
try
:
stream
=
self
.
stream
except
RawPostDataException
:
if
not
hasattr
(
self
.
_request
,
'_post'
):
raise
# If request.POST has been accessed in middleware, and a method='POST'
# request was made with 'multipart/form-data', then the request stream
# will already have been exhausted.
if
self
.
_supports_form_parsing
():
return
(
self
.
_request
.
POST
,
self
.
_request
.
FILES
)
stream
=
None
if
stream
is
None
or
media_type
is
None
:
if
stream
is
None
or
media_type
is
None
:
empty_data
=
QueryDict
(
''
,
encoding
=
self
.
_request
.
_encoding
)
empty_data
=
QueryDict
(
''
,
encoding
=
self
.
_request
.
_encoding
)
...
...
tests/test_parsers.py
View file @
be74d111
...
@@ -7,11 +7,16 @@ from django import forms
...
@@ -7,11 +7,16 @@ from django import forms
from
django.core.files.uploadhandler
import
(
from
django.core.files.uploadhandler
import
(
MemoryFileUploadHandler
,
TemporaryFileUploadHandler
MemoryFileUploadHandler
,
TemporaryFileUploadHandler
)
)
from
django.http.request
import
RawPostDataException
from
django.test
import
TestCase
from
django.test
import
TestCase
from
django.utils.six.moves
import
StringIO
from
django.utils.six.moves
import
StringIO
from
rest_framework.exceptions
import
ParseError
from
rest_framework.exceptions
import
ParseError
from
rest_framework.parsers
import
FileUploadParser
,
FormParser
from
rest_framework.parsers
import
(
FileUploadParser
,
FormParser
,
JSONParser
,
MultiPartParser
)
from
rest_framework.request
import
Request
from
rest_framework.test
import
APIRequestFactory
class
Form
(
forms
.
Form
):
class
Form
(
forms
.
Form
):
...
@@ -122,3 +127,39 @@ class TestFileUploadParser(TestCase):
...
@@ -122,3 +127,39 @@ class TestFileUploadParser(TestCase):
def
__replace_content_disposition
(
self
,
disposition
):
def
__replace_content_disposition
(
self
,
disposition
):
self
.
parser_context
[
'request'
]
.
META
[
'HTTP_CONTENT_DISPOSITION'
]
=
disposition
self
.
parser_context
[
'request'
]
.
META
[
'HTTP_CONTENT_DISPOSITION'
]
=
disposition
class
TestPOSTAccessed
(
TestCase
):
def
setUp
(
self
):
self
.
factory
=
APIRequestFactory
()
def
test_post_accessed_in_post_method
(
self
):
django_request
=
self
.
factory
.
post
(
'/'
,
{
'foo'
:
'bar'
})
request
=
Request
(
django_request
,
parsers
=
[
FormParser
(),
MultiPartParser
()])
django_request
.
POST
assert
request
.
POST
==
{
'foo'
:
[
'bar'
]}
assert
request
.
data
==
{
'foo'
:
[
'bar'
]}
def
test_post_accessed_in_post_method_with_json_parser
(
self
):
django_request
=
self
.
factory
.
post
(
'/'
,
{
'foo'
:
'bar'
})
request
=
Request
(
django_request
,
parsers
=
[
JSONParser
()])
django_request
.
POST
assert
request
.
POST
==
{}
assert
request
.
data
==
{}
def
test_post_accessed_in_put_method
(
self
):
django_request
=
self
.
factory
.
put
(
'/'
,
{
'foo'
:
'bar'
})
request
=
Request
(
django_request
,
parsers
=
[
FormParser
(),
MultiPartParser
()])
django_request
.
POST
assert
request
.
POST
==
{
'foo'
:
[
'bar'
]}
assert
request
.
data
==
{
'foo'
:
[
'bar'
]}
def
test_request_read_before_parsing
(
self
):
django_request
=
self
.
factory
.
put
(
'/'
,
{
'foo'
:
'bar'
})
request
=
Request
(
django_request
,
parsers
=
[
FormParser
(),
MultiPartParser
()])
django_request
.
read
()
with
pytest
.
raises
(
RawPostDataException
):
request
.
POST
with
pytest
.
raises
(
RawPostDataException
):
request
.
POST
request
.
data
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