From 4b691c402707775c3048a90531024f3bc5be6f91 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 20 Sep 2012 13:06:27 +0100 Subject: Change package name: djangorestframework -> rest_framework --- rest_framework/request.py | 284 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 rest_framework/request.py (limited to 'rest_framework/request.py') diff --git a/rest_framework/request.py b/rest_framework/request.py new file mode 100644 index 00000000..ee5e46d0 --- /dev/null +++ b/rest_framework/request.py @@ -0,0 +1,284 @@ +""" +The :mod:`request` module provides a :class:`Request` class used to wrap the standard `request` +object received in all the views. + +The wrapped request then offers a richer API, in particular : + + - content automatically parsed according to `Content-Type` header, + and available as :meth:`.DATA` + - full support of PUT method, including support for file uploads + - form overloading of HTTP method, content type and content +""" +from StringIO import StringIO + +from rest_framework import exceptions +from rest_framework.settings import api_settings +from rest_framework.utils.mediatypes import is_form_media_type + + +__all__ = ('Request',) + + +class Empty(object): + """ + Placeholder for unset attributes. + Cannot use `None`, as that may be a valid value. + """ + pass + + +def _hasattr(obj, name): + return not getattr(obj, name) is Empty + + +class Request(object): + """ + Wrapper allowing to enhance a standard `HttpRequest` instance. + + Kwargs: + - request(HttpRequest). The original request instance. + - parsers_classes(list/tuple). The parsers to use for parsing the + request content. + - authentication_classes(list/tuple). The authentications used to try + authenticating the request's user. + """ + + _METHOD_PARAM = api_settings.FORM_METHOD_OVERRIDE + _CONTENT_PARAM = api_settings.FORM_CONTENT_OVERRIDE + _CONTENTTYPE_PARAM = api_settings.FORM_CONTENTTYPE_OVERRIDE + + def __init__(self, request, parser_classes=None, authentication_classes=None): + self._request = request + self.parser_classes = parser_classes or () + self.authentication_classes = authentication_classes or () + self._data = Empty + self._files = Empty + self._method = Empty + self._content_type = Empty + self._stream = Empty + + def get_parsers(self): + """ + Instantiates and returns the list of parsers the request will use. + """ + return [parser() for parser in self.parser_classes] + + def get_authentications(self): + """ + Instantiates and returns the list of parsers the request will use. + """ + return [authentication() for authentication in self.authentication_classes] + + @property + def method(self): + """ + Returns the HTTP method. + + This allows the `method` to be overridden by using a hidden `form` + field on a form POST request. + """ + if not _hasattr(self, '_method'): + self._load_method_and_content_type() + return self._method + + @property + def content_type(self): + """ + Returns the content type header. + + This should be used instead of ``request.META.get('HTTP_CONTENT_TYPE')``, + as it allows the content type to be overridden by using a hidden form + field on a form POST request. + """ + if not _hasattr(self, '_content_type'): + self._load_method_and_content_type() + return self._content_type + + @property + def stream(self): + """ + Returns an object that may be used to stream the request content. + """ + if not _hasattr(self, '_stream'): + self._load_stream() + return self._stream + + @property + def DATA(self): + """ + Parses the request body and returns the data. + + Similar to usual behaviour of `request.POST`, except that it handles + arbitrary parsers, and also works on methods other than POST (eg PUT). + """ + if not _hasattr(self, '_data'): + self._load_data_and_files() + return self._data + + @property + def FILES(self): + """ + Parses the request body and returns any files uploaded in the request. + + Similar to usual behaviour of `request.FILES`, except that it handles + arbitrary parsers, and also works on methods other than POST (eg PUT). + """ + if not _hasattr(self, '_files'): + self._load_data_and_files() + return self._files + + @property + def user(self): + """ + Returns the user associated with the current request, as authenticated + by the authentication classes provided to the request. + """ + if not hasattr(self, '_user'): + self._user, self._auth = self._authenticate() + return self._user + + @property + def auth(self): + """ + Returns any non-user authentication information associated with the + request, such as an authentication token. + """ + if not hasattr(self, '_auth'): + self._user, self._auth = self._authenticate() + return self._auth + + def _load_data_and_files(self): + """ + Parses the request content into self.DATA and self.FILES. + """ + if not _hasattr(self, '_content_type'): + self._load_method_and_content_type() + + if not _hasattr(self, '_data'): + self._data, self._files = self._parse() + + def _load_method_and_content_type(self): + """ + Sets the method and content_type, and then check if they've + been overridden. + """ + self._content_type = self.META.get('HTTP_CONTENT_TYPE', + self.META.get('CONTENT_TYPE', '')) + self._perform_form_overloading() + # if the HTTP method was not overloaded, we take the raw HTTP method + if not _hasattr(self, '_method'): + self._method = self._request.method + + def _load_stream(self): + """ + Return the content body of the request, as a stream. + """ + try: + content_length = int(self.META.get('CONTENT_LENGTH', + self.META.get('HTTP_CONTENT_LENGTH'))) + except (ValueError, TypeError): + content_length = 0 + + if content_length == 0: + self._stream = None + elif hasattr(self._request, 'read'): + self._stream = self._request + else: + self._stream = StringIO(self.raw_post_data) + + def _perform_form_overloading(self): + """ + If this is a form POST request, then we need to check if the method and + content/content_type have been overridden by setting them in hidden + form fields or not. + """ + + USE_FORM_OVERLOADING = ( + self._METHOD_PARAM or + (self._CONTENT_PARAM and self._CONTENTTYPE_PARAM) + ) + + # We only need to use form overloading on form POST requests. + if (not USE_FORM_OVERLOADING + or self._request.method != 'POST' + or not is_form_media_type(self._content_type)): + return + + # At this point we're committed to parsing the request as form data. + self._data = self._request.POST + self._files = self._request.FILES + + # Method overloading - change the method and remove the param from the content. + if (self._METHOD_PARAM and + self._METHOD_PARAM in self._data): + self._method = self._data[self._METHOD_PARAM].upper() + self._data.pop(self._METHOD_PARAM) + + # Content overloading - modify the content type, and re-parse. + if (self._CONTENT_PARAM and + self._CONTENTTYPE_PARAM and + self._CONTENT_PARAM in self._data and + self._CONTENTTYPE_PARAM in self._data): + self._content_type = self._data[self._CONTENTTYPE_PARAM] + self._stream = StringIO(self._data[self._CONTENT_PARAM]) + self._data.pop(self._CONTENTTYPE_PARAM) + self._data.pop(self._CONTENT_PARAM) + self._data, self._files = self._parse() + + def _parse(self): + """ + Parse the request content, returning a two-tuple of (data, files) + + May raise an `UnsupportedMediaType`, or `ParseError` exception. + """ + if self.stream is None or self.content_type is None: + return (None, None) + + for parser in self.get_parsers(): + if parser.can_handle_request(self.content_type): + parsed = parser.parse(self.stream, meta=self.META, + upload_handlers=self.upload_handlers) + # Parser classes may return the raw data, or a + # DataAndFiles object. Unpack the result as required. + try: + return (parsed.data, parsed.files) + except AttributeError: + return (parsed, None) + + raise exceptions.UnsupportedMediaType(self._content_type) + + def _authenticate(self): + """ + Attempt to authenticate the request using each authentication instance in turn. + Returns a two-tuple of (user, authtoken). + """ + for authentication in self.get_authentications(): + user_auth_tuple = authentication.authenticate(self) + if not user_auth_tuple is None: + return user_auth_tuple + return self._not_authenticated() + + def _not_authenticated(self): + """ + Return a two-tuple of (user, authtoken), representing an + unauthenticated request. + + By default this will be (AnonymousUser, None). + """ + if api_settings.UNAUTHENTICATED_USER: + user = api_settings.UNAUTHENTICATED_USER() + else: + user = None + + if api_settings.UNAUTHENTICATED_TOKEN: + auth = api_settings.UNAUTHENTICATED_TOKEN() + else: + auth = None + + return (user, auth) + + def __getattr__(self, attr): + """ + Proxy other attributes to the underlying HttpRequest object. + """ + return getattr(self._request, attr) -- cgit v1.2.3 From 7efc6e820580fde5a38cbee5cec05cbc87ce36e4 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 20 Sep 2012 13:22:07 +0100 Subject: Remove dumbass __all__ variables --- rest_framework/request.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'rest_framework/request.py') diff --git a/rest_framework/request.py b/rest_framework/request.py index ee5e46d0..dcf17adf 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -16,9 +16,6 @@ from rest_framework.settings import api_settings from rest_framework.utils.mediatypes import is_form_media_type -__all__ = ('Request',) - - class Empty(object): """ Placeholder for unset attributes. -- cgit v1.2.3 From 728e92f06a86bb18baa73f42433468c4d042affd Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 26 Sep 2012 12:39:39 +0100 Subject: Add request.QUERY_PARAMS --- rest_framework/request.py | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'rest_framework/request.py') diff --git a/rest_framework/request.py b/rest_framework/request.py index dcf17adf..2034ccc6 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -100,6 +100,13 @@ class Request(object): self._load_stream() return self._stream + @property + def QUERY_PARAMS(self): + """ + More semantically correct name for request.GET. + """ + return self._request.GET + @property def DATA(self): """ -- cgit v1.2.3 From 84f775803994ccd82671dd4a6f9b4d87aa36dc31 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 28 Sep 2012 11:53:51 +0100 Subject: Remove support for doctests --- 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 2034ccc6..e254cf8e 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -28,6 +28,22 @@ def _hasattr(obj, name): return not getattr(obj, name) is Empty +def clone_request(request, method): + """ + Internal helper method to clone a request, replacing with a different + HTTP method. Used for checking permissions against other methods. + """ + ret = Request(request._request, + request.parser_classes, + request.authentication_classes) + ret._data = request._data + ret._files = request._files + ret._content_type = request._content_type + ret._stream = request._stream + ret._method = method + return ret + + class Request(object): """ Wrapper allowing to enhance a standard `HttpRequest` instance. -- cgit v1.2.3 From 9d8bce8f5b0915223f57d9fe3d4b63029cfc64c2 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Fri, 5 Oct 2012 14:48:33 +0100 Subject: Remove Parser.can_handle_request() --- rest_framework/request.py | 52 +++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 29 deletions(-) (limited to 'rest_framework/request.py') diff --git a/rest_framework/request.py b/rest_framework/request.py index e254cf8e..ac15defc 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -34,8 +34,8 @@ def clone_request(request, method): HTTP method. Used for checking permissions against other methods. """ ret = Request(request._request, - request.parser_classes, - request.authentication_classes) + request.parsers, + request.authenticators) ret._data = request._data ret._files = request._files ret._content_type = request._content_type @@ -60,27 +60,20 @@ class Request(object): _CONTENT_PARAM = api_settings.FORM_CONTENT_OVERRIDE _CONTENTTYPE_PARAM = api_settings.FORM_CONTENTTYPE_OVERRIDE - def __init__(self, request, parser_classes=None, authentication_classes=None): + def __init__(self, request, parsers=None, authenticators=None, + negotiator=None): self._request = request - self.parser_classes = parser_classes or () - self.authentication_classes = authentication_classes or () + self.parsers = parsers or () + self.authenticators = authenticators or () + self.negotiator = negotiator or self._default_negotiator() self._data = Empty self._files = Empty self._method = Empty self._content_type = Empty self._stream = Empty - def get_parsers(self): - """ - Instantiates and returns the list of parsers the request will use. - """ - return [parser() for parser in self.parser_classes] - - def get_authentications(self): - """ - Instantiates and returns the list of parsers the request will use. - """ - return [authentication() for authentication in self.authentication_classes] + def _default_negotiator(self): + return api_settings.DEFAULT_CONTENT_NEGOTIATION() @property def method(self): @@ -254,26 +247,27 @@ class Request(object): if self.stream is None or self.content_type is None: return (None, None) - for parser in self.get_parsers(): - if parser.can_handle_request(self.content_type): - parsed = parser.parse(self.stream, meta=self.META, - upload_handlers=self.upload_handlers) - # Parser classes may return the raw data, or a - # DataAndFiles object. Unpack the result as required. - try: - return (parsed.data, parsed.files) - except AttributeError: - return (parsed, None) + parser = self.negotiator.select_parser(self.parsers, self.content_type) + + if not parser: + raise exceptions.UnsupportedMediaType(self._content_type) - raise exceptions.UnsupportedMediaType(self._content_type) + parsed = parser.parse(self.stream, meta=self.META, + upload_handlers=self.upload_handlers) + # Parser classes may return the raw data, or a + # DataAndFiles object. Unpack the result as required. + try: + return (parsed.data, parsed.files) + except AttributeError: + return (parsed, None) def _authenticate(self): """ Attempt to authenticate the request using each authentication instance in turn. Returns a two-tuple of (user, authtoken). """ - for authentication in self.get_authentications(): - user_auth_tuple = authentication.authenticate(self) + for authenticator in self.authenticators: + user_auth_tuple = authenticator.authenticate(self) if not user_auth_tuple is None: return user_auth_tuple return self._not_authenticated() -- cgit v1.2.3 From 4a21b3557edb3b901b86d3a888c44f772e33b922 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 8 Oct 2012 17:10:50 +0100 Subject: Fix fiddly content-overloading bug --- rest_framework/request.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'rest_framework/request.py') diff --git a/rest_framework/request.py b/rest_framework/request.py index ac15defc..3ce93181 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -227,16 +227,14 @@ class Request(object): self._method = self._data[self._METHOD_PARAM].upper() self._data.pop(self._METHOD_PARAM) - # Content overloading - modify the content type, and re-parse. + # Content overloading - modify the content type, and force re-parse. if (self._CONTENT_PARAM and self._CONTENTTYPE_PARAM and self._CONTENT_PARAM in self._data and self._CONTENTTYPE_PARAM in self._data): self._content_type = self._data[self._CONTENTTYPE_PARAM] self._stream = StringIO(self._data[self._CONTENT_PARAM]) - self._data.pop(self._CONTENTTYPE_PARAM) - self._data.pop(self._CONTENT_PARAM) - self._data, self._files = self._parse() + self._data, self._files = (Empty, Empty) def _parse(self): """ @@ -250,7 +248,7 @@ class Request(object): parser = self.negotiator.select_parser(self.parsers, self.content_type) if not parser: - raise exceptions.UnsupportedMediaType(self._content_type) + raise exceptions.UnsupportedMediaType(self.content_type) parsed = parser.parse(self.stream, meta=self.META, upload_handlers=self.upload_handlers) -- cgit v1.2.3 From 65f592866c5cd5103e99ed453543807bcbdaa9da Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 8 Oct 2012 17:53:18 +0100 Subject: Fix issue where required fields were not being properly validated. Also make model fields with a default value be not required --- rest_framework/request.py | 1 - 1 file changed, 1 deletion(-) (limited to 'rest_framework/request.py') diff --git a/rest_framework/request.py b/rest_framework/request.py index 3ce93181..3725b3c9 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -225,7 +225,6 @@ class Request(object): if (self._METHOD_PARAM and self._METHOD_PARAM in self._data): self._method = self._data[self._METHOD_PARAM].upper() - self._data.pop(self._METHOD_PARAM) # Content overloading - modify the content type, and force re-parse. if (self._CONTENT_PARAM and -- cgit v1.2.3 From 7c4d50f621a9c0668b8f8992751de6b2d7bcbe29 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 9 Oct 2012 12:48:49 +0100 Subject: Fix browseable API form display error for authenticated permissions --- 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 3725b3c9..0a57d376 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -41,6 +41,10 @@ def clone_request(request, method): ret._content_type = request._content_type ret._stream = request._stream ret._method = method + if hasattr(request, '_user'): + ret._user = request._user + if hasattr(request, '_auth'): + ret._auth = request._auth return ret -- cgit v1.2.3 From 7608cf1193fd555f31eb9a3d98c6f258720f8022 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sat, 13 Oct 2012 15:07:43 +0100 Subject: Improve documentation for Requests --- 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 0a57d376..7267b368 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -96,7 +96,7 @@ class Request(object): """ Returns the content type header. - This should be used instead of ``request.META.get('HTTP_CONTENT_TYPE')``, + This should be used instead of `request.META.get('HTTP_CONTENT_TYPE')`, as it allows the content type to be overridden by using a hidden form field on a form POST request. """ -- cgit v1.2.3 From 9c1fba3483b7e81da0744464dcf23a5f12711de2 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 15 Oct 2012 13:27:50 +0100 Subject: Tweak parsers to take parser_context --- rest_framework/request.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) (limited to 'rest_framework/request.py') diff --git a/rest_framework/request.py b/rest_framework/request.py index 7267b368..6f9cf09a 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -11,9 +11,18 @@ The wrapped request then offers a richer API, in particular : """ from StringIO import StringIO +from django.http.multipartparser import parse_header from rest_framework import exceptions from rest_framework.settings import api_settings -from rest_framework.utils.mediatypes import is_form_media_type + + +def is_form_media_type(media_type): + """ + Return True if the media type is a valid form media type. + """ + base_media_type, params = parse_header(media_type) + return base_media_type == 'application/x-www-form-urlencoded' or \ + base_media_type == 'multipart/form-data' class Empty(object): @@ -35,7 +44,8 @@ def clone_request(request, method): """ ret = Request(request._request, request.parsers, - request.authenticators) + request.authenticators, + request.parser_context) ret._data = request._data ret._files = request._files ret._content_type = request._content_type @@ -65,20 +75,30 @@ class Request(object): _CONTENTTYPE_PARAM = api_settings.FORM_CONTENTTYPE_OVERRIDE def __init__(self, request, parsers=None, authenticators=None, - negotiator=None): + negotiator=None, parser_context=None): self._request = request self.parsers = parsers or () self.authenticators = authenticators or () self.negotiator = negotiator or self._default_negotiator() + self.parser_context = parser_context self._data = Empty self._files = Empty self._method = Empty self._content_type = Empty self._stream = Empty + if self.parser_context is None: + self.parser_context = self._default_parser_context(request) + def _default_negotiator(self): return api_settings.DEFAULT_CONTENT_NEGOTIATION() + def _default_parser_context(self, request): + return { + 'upload_handlers': request.upload_handlers, + 'meta': request.META, + } + @property def method(self): """ @@ -253,8 +273,7 @@ class Request(object): if not parser: raise exceptions.UnsupportedMediaType(self.content_type) - parsed = parser.parse(self.stream, meta=self.META, - upload_handlers=self.upload_handlers) + parsed = parser.parse(self.stream, self.parser_context) # Parser classes may return the raw data, or a # DataAndFiles object. Unpack the result as required. try: -- cgit v1.2.3 From 4231995fbd80e45991975ab81d9e570a9f4b72d0 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 17 Oct 2012 22:19:59 +0100 Subject: parser_context includes `view`, `request`, `args`, `kwargs`. (Not `meta` and `upload_handlers`) Consistency with renderer API. --- rest_framework/request.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'rest_framework/request.py') diff --git a/rest_framework/request.py b/rest_framework/request.py index 6f9cf09a..d739d27d 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -88,17 +88,12 @@ class Request(object): self._stream = Empty if self.parser_context is None: - self.parser_context = self._default_parser_context(request) + self.parser_context = {} + self.parser_context['request'] = self def _default_negotiator(self): return api_settings.DEFAULT_CONTENT_NEGOTIATION() - def _default_parser_context(self, request): - return { - 'upload_handlers': request.upload_handlers, - 'meta': request.META, - } - @property def method(self): """ -- cgit v1.2.3 From fb56f215ae50da0aebe99e05036ece259fd3e6f1 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 17 Oct 2012 22:39:07 +0100 Subject: Added `media_type` to `.parse()` - Consistency with renderer API. --- rest_framework/request.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'rest_framework/request.py') diff --git a/rest_framework/request.py b/rest_framework/request.py index d739d27d..b9d55de4 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -260,15 +260,19 @@ class Request(object): May raise an `UnsupportedMediaType`, or `ParseError` exception. """ - if self.stream is None or self.content_type is None: + stream = self.stream + media_type = self.content_type + + if stream is None or media_type is None: return (None, None) - parser = self.negotiator.select_parser(self.parsers, self.content_type) + parser = self.negotiator.select_parser(self.parsers, media_type) if not parser: - raise exceptions.UnsupportedMediaType(self.content_type) + raise exceptions.UnsupportedMediaType(media_type) + + parsed = parser.parse(stream, media_type, self.parser_context) - parsed = parser.parse(self.stream, self.parser_context) # Parser classes may return the raw data, or a # DataAndFiles object. Unpack the result as required. try: -- cgit v1.2.3 From e126b615420fed12af58675cb4bb52e749b006bd Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 17 Oct 2012 22:58:18 +0100 Subject: Negotiation API finalized. .select_renderers and .select_parsers --- 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 b9d55de4..b212680f 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -266,7 +266,7 @@ class Request(object): if stream is None or media_type is None: return (None, None) - parser = self.negotiator.select_parser(self.parsers, media_type) + parser = self.negotiator.select_parser(self, self.parsers) if not parser: raise exceptions.UnsupportedMediaType(media_type) -- cgit v1.2.3 From fed235dd0135c3eb98bb218a51f01ace5ddd3782 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Wed, 17 Oct 2012 23:09:11 +0100 Subject: Make settings consistent with corrosponding view attributes --- 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 b212680f..5870be82 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -92,7 +92,7 @@ class Request(object): self.parser_context['request'] = self def _default_negotiator(self): - return api_settings.DEFAULT_CONTENT_NEGOTIATION() + return api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS() @property def method(self): -- cgit v1.2.3 From 44207a347ac765d900f15b65bdd24dbf8eb9ead2 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sat, 27 Oct 2012 10:32:49 +0100 Subject: pep8 --- rest_framework/request.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'rest_framework/request.py') diff --git a/rest_framework/request.py b/rest_framework/request.py index 5870be82..a1827ba4 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -21,8 +21,8 @@ def is_form_media_type(media_type): Return True if the media type is a valid form media type. """ base_media_type, params = parse_header(media_type) - return base_media_type == 'application/x-www-form-urlencoded' or \ - base_media_type == 'multipart/form-data' + return (base_media_type == 'application/x-www-form-urlencoded' or + base_media_type == 'multipart/form-data') class Empty(object): -- cgit v1.2.3