From 2859eaf524bca23f27e666d24a0b63ba61698a76 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 26 Sep 2014 10:46:52 +0100 Subject: request.data attribute --- rest_framework/request.py | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'rest_framework/request.py') 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,12 +198,25 @@ 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): """ @@ -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 -- cgit v1.2.3 From 14ae52a24e93063f77c6010269bf9cd3316627fe Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 8 Oct 2014 16:09:37 +0100 Subject: More gradual deprecation --- rest_framework/request.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'rest_framework/request.py') diff --git a/rest_framework/request.py b/rest_framework/request.py index d80baa70..d4352742 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -18,6 +18,7 @@ from rest_framework import HTTP_HEADER_ENCODING from rest_framework import exceptions from rest_framework.compat import BytesIO from rest_framework.settings import api_settings +import warnings def is_form_media_type(media_type): @@ -209,6 +210,11 @@ class Request(object): """ Synonym for `.query_params`, for backwards compatibility. """ + warnings.warn( + "`request.QUERY_PARAMS` is pending deprecation. Use `request.query_params` instead.", + PendingDeprecationWarning, + stacklevel=1 + ) return self._request.GET @property @@ -225,6 +231,11 @@ class Request(object): Similar to usual behaviour of `request.POST`, except that it handles arbitrary parsers, and also works on methods other than POST (eg PUT). """ + warnings.warn( + "`request.DATA` is pending deprecation. Use `request.data` instead.", + PendingDeprecationWarning, + stacklevel=1 + ) if not _hasattr(self, '_data'): self._load_data_and_files() return self._data @@ -237,6 +248,11 @@ class Request(object): Similar to usual behaviour of `request.FILES`, except that it handles arbitrary parsers, and also works on methods other than POST (eg PUT). """ + warnings.warn( + "`request.FILES` is pending deprecation. Use `request.data` instead.", + PendingDeprecationWarning, + stacklevel=1 + ) if not _hasattr(self, '_files'): self._load_data_and_files() return self._files -- cgit v1.2.3 From 2daf085100b32fd4c13add0fcfa2dbb97722de4a Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 5 Nov 2014 11:08:32 +0000 Subject: Copy accepted_renderer and accepted_media_type when cloing a request. Closes #1950. --- rest_framework/request.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'rest_framework/request.py') diff --git a/rest_framework/request.py b/rest_framework/request.py index d4352742..096b3042 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -103,6 +103,10 @@ def clone_request(request, method): ret._auth = request._auth if hasattr(request, '_authenticator'): ret._authenticator = request._authenticator + if hasattr(request, 'accepted_renderer'): + ret.accepted_renderer = request.accepted_renderer + if hasattr(request, 'accepted_media_type'): + ret.accepted_media_type = request.accepted_media_type return ret -- cgit v1.2.3 From 2e726e22a394347b7337eb38a2a3a1b0ccde88bc Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 25 Nov 2014 11:42:43 +0000 Subject: request.DATA, request.FILES -> request.data --- rest_framework/request.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rest_framework/request.py') diff --git a/rest_framework/request.py b/rest_framework/request.py index 096b3042..d7e74674 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -310,7 +310,7 @@ class Request(object): def _load_data_and_files(self): """ - Parses the request content into self.DATA and self.FILES. + Parses the request content into `self.data`. """ if not _hasattr(self, '_content_type'): self._load_method_and_content_type() -- cgit v1.2.3