aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework/request.py
diff options
context:
space:
mode:
authorTom Christie2014-09-26 10:46:52 +0100
committerTom Christie2014-09-26 10:46:52 +0100
commit2859eaf524bca23f27e666d24a0b63ba61698a76 (patch)
tree8acd1be737f9052577e130608a764d6197551d93 /rest_framework/request.py
parent417fe1b675bd1d42518fb89a6f81547caef5b735 (diff)
downloaddjango-rest-framework-2859eaf524bca23f27e666d24a0b63ba61698a76.tar.bz2
request.data attribute
Diffstat (limited to 'rest_framework/request.py')
-rw-r--r--rest_framework/request.py37
1 files changed, 34 insertions, 3 deletions
diff --git a/rest_framework/request.py b/rest_framework/request.py
index 27532661..d80baa70 100644
--- a/rest_framework/request.py
+++ b/rest_framework/request.py
@@ -4,7 +4,7 @@ The Request class is used as a wrapper around the standard request object.
The wrapped request then offers a richer API, in particular :
- content automatically parsed according to `Content-Type` header,
- and available as `request.DATA`
+ and available as `request.data`
- full support of PUT method, including support for file uploads
- form overloading of HTTP method, content type and content
"""
@@ -13,6 +13,7 @@ from django.conf import settings
from django.http import QueryDict
from django.http.multipartparser import parse_header
from django.utils.datastructures import MultiValueDict
+from django.utils.datastructures import MergeDict as DjangoMergeDict
from rest_framework import HTTP_HEADER_ENCODING
from rest_framework import exceptions
from rest_framework.compat import BytesIO
@@ -58,6 +59,15 @@ class override_method(object):
self.view.action = self.action
+class MergeDict(DjangoMergeDict, dict):
+ """
+ Using this as a workaround until the parsers API is properly
+ addressed in 3.1.
+ """
+ def __init__(self, *dicts):
+ self.dicts = dicts
+
+
class Empty(object):
"""
Placeholder for unset attributes.
@@ -82,6 +92,7 @@ def clone_request(request, method):
parser_context=request.parser_context)
ret._data = request._data
ret._files = request._files
+ ret._full_data = request._full_data
ret._content_type = request._content_type
ret._stream = request._stream
ret._method = method
@@ -133,6 +144,7 @@ class Request(object):
self.parser_context = parser_context
self._data = Empty
self._files = Empty
+ self._full_data = Empty
self._method = Empty
self._content_type = Empty
self._stream = Empty
@@ -186,13 +198,26 @@ class Request(object):
return self._stream
@property
- def QUERY_PARAMS(self):
+ def query_params(self):
"""
More semantically correct name for request.GET.
"""
return self._request.GET
@property
+ def QUERY_PARAMS(self):
+ """
+ Synonym for `.query_params`, for backwards compatibility.
+ """
+ return self._request.GET
+
+ @property
+ def data(self):
+ if not _hasattr(self, '_full_data'):
+ self._load_data_and_files()
+ return self._full_data
+
+ @property
def DATA(self):
"""
Parses the request body and returns the data.
@@ -272,6 +297,10 @@ class Request(object):
if not _hasattr(self, '_data'):
self._data, self._files = self._parse()
+ if self._files:
+ self._full_data = MergeDict(self._data, self._files)
+ else:
+ self._full_data = self._data
def _load_method_and_content_type(self):
"""
@@ -333,6 +362,7 @@ class Request(object):
# At this point we're committed to parsing the request as form data.
self._data = self._request.POST
self._files = self._request.FILES
+ self._full_data = MergeDict(self._data, self._files)
# Method overloading - change the method and remove the param from the content.
if (
@@ -350,7 +380,7 @@ class Request(object):
):
self._content_type = self._data[self._CONTENTTYPE_PARAM]
self._stream = BytesIO(self._data[self._CONTENT_PARAM].encode(self.parser_context['encoding']))
- self._data, self._files = (Empty, Empty)
+ self._data, self._files, self._full_data = (Empty, Empty, Empty)
def _parse(self):
"""
@@ -380,6 +410,7 @@ class Request(object):
# logging the request or similar.
self._data = QueryDict('', encoding=self._request._encoding)
self._files = MultiValueDict()
+ self._full_data = self._data
raise
# Parser classes may return the raw data, or a