mirror of
https://github.com/django/django.git
synced 2025-04-10 08:19:39 +00:00
Added request.parsers
This commit is contained in:
parent
476501242c
commit
31aabb20c2
@ -19,6 +19,7 @@ from django.http import (
|
||||
HttpResponseServerError,
|
||||
QueryDict,
|
||||
parse_cookie,
|
||||
parsers,
|
||||
)
|
||||
from django.urls import set_script_prefix
|
||||
from django.utils.functional import cached_property
|
||||
@ -111,6 +112,10 @@ class ASGIRequest(HttpRequest):
|
||||
self._stream = body_file
|
||||
# Other bits.
|
||||
self.resolver_match = None
|
||||
self._parsers = [
|
||||
parsers.FormParser(),
|
||||
parsers.MultiPartParser(),
|
||||
]
|
||||
|
||||
@cached_property
|
||||
def GET(self):
|
||||
|
@ -3,7 +3,7 @@ from io import IOBase
|
||||
from django.conf import settings
|
||||
from django.core import signals
|
||||
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.utils.encoding import repercent_broken_unicode
|
||||
from django.utils.functional import cached_property
|
||||
@ -78,6 +78,10 @@ class WSGIRequest(HttpRequest):
|
||||
self._stream = LimitedStream(self.environ["wsgi.input"], content_length)
|
||||
self._read_started = False
|
||||
self.resolver_match = None
|
||||
self._parsers = [
|
||||
parsers.FormParser(),
|
||||
parsers.MultiPartParser(),
|
||||
]
|
||||
|
||||
def _get_scheme(self):
|
||||
return self.environ.get("wsgi.url_scheme")
|
||||
|
@ -69,6 +69,10 @@ class HttpRequest:
|
||||
self.resolver_match = None
|
||||
self.content_type = None
|
||||
self.content_params = None
|
||||
self._parsers = [
|
||||
parsers.FormParser(),
|
||||
parsers.MultiPartParser(),
|
||||
]
|
||||
|
||||
def __repr__(self):
|
||||
if self.method is None or not self.get_full_path():
|
||||
@ -417,6 +421,19 @@ class HttpRequest:
|
||||
def readlines(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):
|
||||
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
|
||||
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.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):
|
||||
parser = MultiPartParser()
|
||||
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.assertTrue(parser.can_handle("text/*"), 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