mirror of
https://github.com/django/django.git
synced 2025-06-05 03:29:12 +00:00
Added request.parsers
This commit is contained in:
parent
476501242c
commit
31aabb20c2
@ -19,6 +19,7 @@ from django.http import (
|
|||||||
HttpResponseServerError,
|
HttpResponseServerError,
|
||||||
QueryDict,
|
QueryDict,
|
||||||
parse_cookie,
|
parse_cookie,
|
||||||
|
parsers,
|
||||||
)
|
)
|
||||||
from django.urls import set_script_prefix
|
from django.urls import set_script_prefix
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
@ -111,6 +112,10 @@ class ASGIRequest(HttpRequest):
|
|||||||
self._stream = body_file
|
self._stream = body_file
|
||||||
# Other bits.
|
# Other bits.
|
||||||
self.resolver_match = None
|
self.resolver_match = None
|
||||||
|
self._parsers = [
|
||||||
|
parsers.FormParser(),
|
||||||
|
parsers.MultiPartParser(),
|
||||||
|
]
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def GET(self):
|
def GET(self):
|
||||||
|
@ -3,7 +3,7 @@ from io import IOBase
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core import signals
|
from django.core import signals
|
||||||
from django.core.handlers import base
|
from django.core.handlers import base
|
||||||
from django.http import HttpRequest, QueryDict, parse_cookie
|
from django.http import HttpRequest, QueryDict, parse_cookie, parsers
|
||||||
from django.urls import set_script_prefix
|
from django.urls import set_script_prefix
|
||||||
from django.utils.encoding import repercent_broken_unicode
|
from django.utils.encoding import repercent_broken_unicode
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
@ -78,6 +78,10 @@ class WSGIRequest(HttpRequest):
|
|||||||
self._stream = LimitedStream(self.environ["wsgi.input"], content_length)
|
self._stream = LimitedStream(self.environ["wsgi.input"], content_length)
|
||||||
self._read_started = False
|
self._read_started = False
|
||||||
self.resolver_match = None
|
self.resolver_match = None
|
||||||
|
self._parsers = [
|
||||||
|
parsers.FormParser(),
|
||||||
|
parsers.MultiPartParser(),
|
||||||
|
]
|
||||||
|
|
||||||
def _get_scheme(self):
|
def _get_scheme(self):
|
||||||
return self.environ.get("wsgi.url_scheme")
|
return self.environ.get("wsgi.url_scheme")
|
||||||
|
@ -69,6 +69,10 @@ class HttpRequest:
|
|||||||
self.resolver_match = None
|
self.resolver_match = None
|
||||||
self.content_type = None
|
self.content_type = None
|
||||||
self.content_params = None
|
self.content_params = None
|
||||||
|
self._parsers = [
|
||||||
|
parsers.FormParser(),
|
||||||
|
parsers.MultiPartParser(),
|
||||||
|
]
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if self.method is None or not self.get_full_path():
|
if self.method is None or not self.get_full_path():
|
||||||
@ -417,6 +421,19 @@ class HttpRequest:
|
|||||||
def readlines(self):
|
def readlines(self):
|
||||||
return list(self)
|
return list(self)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def parsers(self):
|
||||||
|
return self._parsers
|
||||||
|
|
||||||
|
@parsers.setter
|
||||||
|
def parsers(self, parsers):
|
||||||
|
# TODO Also check for _data once added
|
||||||
|
if hasattr(self, "_files"):
|
||||||
|
raise AttributeError(
|
||||||
|
"You cannot change parsers after processing the request's content."
|
||||||
|
)
|
||||||
|
self._parsers = parsers
|
||||||
|
|
||||||
|
|
||||||
class HttpHeaders(CaseInsensitiveMapping):
|
class HttpHeaders(CaseInsensitiveMapping):
|
||||||
HTTP_PREFIX = "HTTP_"
|
HTTP_PREFIX = "HTTP_"
|
||||||
|
@ -56,3 +56,20 @@ Parses HTML form content (). The ``parse()`` method returns a
|
|||||||
|
|
||||||
Parses multipart form content and supports file uploads. The method returns
|
Parses multipart form content and supports file uploads. The method returns
|
||||||
a ``QueryDict`` for ``data`` and an ``MultiValueDict`` for ``FILES``.
|
a ``QueryDict`` for ``data`` and an ``MultiValueDict`` for ``FILES``.
|
||||||
|
|
||||||
|
HttpRequest.Parsers
|
||||||
|
===================
|
||||||
|
|
||||||
|
``HttpRequest.parsers`` returns a list of parsers to be used when parsing a
|
||||||
|
request's content. By default, the parsers list will be Django's included
|
||||||
|
parsers (``FormParser, ``MultiPartParser``).
|
||||||
|
|
||||||
|
Parsers can be customised by setting a list of parsers to be used on the
|
||||||
|
request. This could be in a middleware or in a view, but must be done before
|
||||||
|
``data`` or ``FILES`` is accessed. For example:
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
def index(request):
|
||||||
|
request.parsers = [MyCustomParser(), FormParser(), ...]
|
||||||
|
...
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
from unittest import TestCase
|
from django.core.handlers.wsgi import WSGIRequest
|
||||||
|
from django.http import HttpRequest
|
||||||
from django.http.parsers import BaseParser, FormParser, MultiPartParser
|
from django.http.parsers import BaseParser, FormParser, MultiPartParser
|
||||||
|
from django.test import SimpleTestCase
|
||||||
|
from django.test.client import FakePayload
|
||||||
|
from django.utils.http import urlencode
|
||||||
|
|
||||||
|
|
||||||
class TestParsers(TestCase):
|
class TestParsers(SimpleTestCase):
|
||||||
def test_can_handle(self):
|
def test_can_handle(self):
|
||||||
parser = MultiPartParser()
|
parser = MultiPartParser()
|
||||||
self.assertIs(parser.can_handle("multipart/form-data"), True)
|
self.assertIs(parser.can_handle("multipart/form-data"), True)
|
||||||
@ -25,3 +28,34 @@ class TestParsers(TestCase):
|
|||||||
self.assertIs(parser.can_handle("application/json"), False)
|
self.assertIs(parser.can_handle("application/json"), False)
|
||||||
self.assertTrue(parser.can_handle("text/*"), True)
|
self.assertTrue(parser.can_handle("text/*"), True)
|
||||||
self.assertTrue(parser.can_handle("text/csv"), True)
|
self.assertTrue(parser.can_handle("text/csv"), True)
|
||||||
|
|
||||||
|
def test_request_parser_no_setting(self):
|
||||||
|
request = HttpRequest()
|
||||||
|
form, multipart = request.parsers
|
||||||
|
self.assertIsInstance(form, FormParser)
|
||||||
|
self.assertIsInstance(multipart, MultiPartParser)
|
||||||
|
|
||||||
|
def test_set_parser(self):
|
||||||
|
request = HttpRequest()
|
||||||
|
request.parsers = [FormParser()]
|
||||||
|
|
||||||
|
self.assertEqual(len(request.parsers), 1)
|
||||||
|
self.assertIsInstance(request.parsers[0], FormParser)
|
||||||
|
|
||||||
|
def test_set_parsers_following_files_access(self):
|
||||||
|
payload = FakePayload(urlencode({"key": "value"}))
|
||||||
|
request = WSGIRequest(
|
||||||
|
{
|
||||||
|
"REQUEST_METHOD": "POST",
|
||||||
|
"CONTENT_LENGTH": len(payload),
|
||||||
|
"CONTENT_TYPE": "application/x-www-form-urlencoded",
|
||||||
|
"wsgi.input": payload,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
# can set parsers
|
||||||
|
request.parsers = []
|
||||||
|
# access files
|
||||||
|
request.FILES
|
||||||
|
msg = "You cannot change parsers after processing the request's content."
|
||||||
|
with self.assertRaisesMessage(AttributeError, msg):
|
||||||
|
request.parsers = []
|
||||||
|
Loading…
x
Reference in New Issue
Block a user