From 53b29f0902a52f7020c95ab7488a61208b8ee8a2 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Sat, 31 Jan 2015 08:27:17 +0000 Subject: _closable_objects as an empty list, not deleted --- rest_framework/response.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'rest_framework') diff --git a/rest_framework/response.py b/rest_framework/response.py index 7f90bae1..c21c60a2 100644 --- a/rest_framework/response.py +++ b/rest_framework/response.py @@ -86,8 +86,9 @@ class Response(SimpleTemplateResponse): state = super(Response, self).__getstate__() for key in ( 'accepted_renderer', 'renderer_context', 'resolver_match', - 'client', 'request', 'wsgi_request', '_closable_objects' + 'client', 'request', 'wsgi_request' ): if key in state: del state[key] + state['_closable_objects'] = [] return state -- cgit v1.2.3 From 8f1d42e7d5146e19842d2837259284f8730b451d Mon Sep 17 00:00:00 2001 From: Omer Katz Date: Mon, 2 Feb 2015 10:50:54 +0200 Subject: Fixed typos in docstrings. --- rest_framework/serializers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'rest_framework') diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 42d1e370..2fd907ec 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -633,11 +633,11 @@ def raise_errors_on_nested_writes(method_name, serializer, validated_data): If we don't do this explicitly they'd get a less helpful error when calling `.save()` on the serializer. - We don't *automatically* support these sorts of nested writes brecause + We don't *automatically* support these sorts of nested writes because there are too many ambiguities to define a default behavior. Eg. Suppose we have a `UserSerializer` with a nested profile. How should - we handle the case of an update, where the `profile` realtionship does + we handle the case of an update, where the `profile` relationship does not exist? Any of the following might be valid: * Raise an application error. -- cgit v1.2.3 From 4b65e9e42be068ad3e742692262451f8836f09d3 Mon Sep 17 00:00:00 2001 From: Jason Yan Date: Mon, 2 Feb 2015 16:14:34 -0800 Subject: Fixed missing whitespace in error string. --- rest_framework/serializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rest_framework') diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 2fd907ec..d76658b0 100644 --- a/rest_framework/serializers.py +++ b/rest_framework/serializers.py @@ -177,7 +177,7 @@ class BaseSerializer(Field): ) assert hasattr(self, 'initial_data'), ( - 'Cannot call `.is_valid()` as no `data=` keyword argument was' + 'Cannot call `.is_valid()` as no `data=` keyword argument was ' 'passed when instantiating the serializer instance.' ) -- cgit v1.2.3 From 7bb5fd270da98d8957efb4bf0e4bd4679ddbcf5f Mon Sep 17 00:00:00 2001 From: Greg Kempe Date: Wed, 4 Feb 2015 16:03:03 +0200 Subject: FIX: Don't default to list in method args Fixes @list_route and @detail_route so that they don't initialize their `methods` parameter as a list. In some cases the list gets cleared, and the result is that default parameter is now empty, and may get reused unexpectedly.--- rest_framework/decorators.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'rest_framework') diff --git a/rest_framework/decorators.py b/rest_framework/decorators.py index 325435b3..a68227c1 100644 --- a/rest_framework/decorators.py +++ b/rest_framework/decorators.py @@ -109,10 +109,12 @@ def permission_classes(permission_classes): return decorator -def detail_route(methods=['get'], **kwargs): +def detail_route(methods=None, **kwargs): """ Used to mark a method on a ViewSet that should be routed for detail requests. """ + if methods is None: + methods = ['get'] def decorator(func): func.bind_to_methods = methods func.detail = True @@ -121,10 +123,12 @@ def detail_route(methods=['get'], **kwargs): return decorator -def list_route(methods=['get'], **kwargs): +def list_route(methods=None, **kwargs): """ Used to mark a method on a ViewSet that should be routed for list requests. """ + if methods is None: + methods = ['get'] def decorator(func): func.bind_to_methods = methods func.detail = False -- cgit v1.2.3 From 58e7bbc8ecad8016cc18f7dbd31b235cb515b785 Mon Sep 17 00:00:00 2001 From: Ofir Ovadia Date: Wed, 4 Feb 2015 16:08:41 +0200 Subject: Prefetching the user object when getting the token in TokenAuthentication. Since the user object is fetched 4 lines after getting Token from the database, this removes a DB query for each token-authenticated request. --- rest_framework/authentication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'rest_framework') diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py index 4832ad33..f7601fb1 100644 --- a/rest_framework/authentication.py +++ b/rest_framework/authentication.py @@ -167,7 +167,7 @@ class TokenAuthentication(BaseAuthentication): def authenticate_credentials(self, key): try: - token = self.model.objects.get(key=key) + token = self.model.objects.select_related('user').get(key=key) except self.model.DoesNotExist: raise exceptions.AuthenticationFailed('Invalid token') -- cgit v1.2.3 From d920683237bd2eb17d110a80fc09708a67340f01 Mon Sep 17 00:00:00 2001 From: Greg Kempe Date: Wed, 4 Feb 2015 16:13:30 +0200 Subject: Use inline if --- rest_framework/decorators.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'rest_framework') diff --git a/rest_framework/decorators.py b/rest_framework/decorators.py index a68227c1..7604eae1 100644 --- a/rest_framework/decorators.py +++ b/rest_framework/decorators.py @@ -18,8 +18,7 @@ def api_view(http_method_names=None): Decorator that converts a function-based view into an APIView subclass. Takes a list of allowed methods for the view as an argument. """ - if http_method_names is None: - http_method_names = ['GET'] + http_method_names = ['GET'] if http_method_names is None else http_method_names def decorator(func): @@ -113,8 +112,8 @@ def detail_route(methods=None, **kwargs): """ Used to mark a method on a ViewSet that should be routed for detail requests. """ - if methods is None: - methods = ['get'] + methods = ['get'] if methods is None else methods + def decorator(func): func.bind_to_methods = methods func.detail = True @@ -127,8 +126,8 @@ def list_route(methods=None, **kwargs): """ Used to mark a method on a ViewSet that should be routed for list requests. """ - if methods is None: - methods = ['get'] + methods = ['get'] if methods is None else methods + def decorator(func): func.bind_to_methods = methods func.detail = False -- cgit v1.2.3 From e13d2af1374c8a2b2146e1126d9406bfb4bbd9ec Mon Sep 17 00:00:00 2001 From: Greg Kempe Date: Wed, 4 Feb 2015 16:26:23 +0200 Subject: Parens around if clause --- rest_framework/decorators.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'rest_framework') diff --git a/rest_framework/decorators.py b/rest_framework/decorators.py index 7604eae1..21de1acf 100644 --- a/rest_framework/decorators.py +++ b/rest_framework/decorators.py @@ -18,7 +18,7 @@ def api_view(http_method_names=None): Decorator that converts a function-based view into an APIView subclass. Takes a list of allowed methods for the view as an argument. """ - http_method_names = ['GET'] if http_method_names is None else http_method_names + http_method_names = ['GET'] if (http_method_names is None) else http_method_names def decorator(func): @@ -112,7 +112,7 @@ def detail_route(methods=None, **kwargs): """ Used to mark a method on a ViewSet that should be routed for detail requests. """ - methods = ['get'] if methods is None else methods + methods = ['get'] if (methods is None) else methods def decorator(func): func.bind_to_methods = methods @@ -126,7 +126,7 @@ def list_route(methods=None, **kwargs): """ Used to mark a method on a ViewSet that should be routed for list requests. """ - methods = ['get'] if methods is None else methods + methods = ['get'] if (methods is None) else methods def decorator(func): func.bind_to_methods = methods -- cgit v1.2.3 From fffde8a63be7660e716672c500f0f2bd66c7d345 Mon Sep 17 00:00:00 2001 From: Kaptian Date: Thu, 5 Feb 2015 13:27:26 -0800 Subject: Update throttling.py Use pk pseudo attribute for identifying the user (in case the user model is not the default and has a different column name for the unique id)--- rest_framework/throttling.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'rest_framework') diff --git a/rest_framework/throttling.py b/rest_framework/throttling.py index 0f10136d..261fc246 100644 --- a/rest_framework/throttling.py +++ b/rest_framework/throttling.py @@ -191,7 +191,7 @@ class UserRateThrottle(SimpleRateThrottle): def get_cache_key(self, request, view): if request.user.is_authenticated(): - ident = request.user.id + ident = request.user.pk else: ident = self.get_ident(request) @@ -239,7 +239,7 @@ class ScopedRateThrottle(SimpleRateThrottle): with the '.throttle_scope` property of the view. """ if request.user.is_authenticated(): - ident = request.user.id + ident = request.user.pk else: ident = self.get_ident(request) -- cgit v1.2.3 From d13c807616030b285589cec2fddf4e34a8e22b4a Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 9 Feb 2015 17:02:54 +0000 Subject: Fix misleading AttributeErrors --- rest_framework/request.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'rest_framework') diff --git a/rest_framework/request.py b/rest_framework/request.py index cfbbdecc..38fcf9c0 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -18,6 +18,7 @@ from django.utils.six import BytesIO from rest_framework import HTTP_HEADER_ENCODING from rest_framework import exceptions from rest_framework.settings import api_settings +import sys import warnings @@ -485,8 +486,16 @@ class Request(object): else: self.auth = None - def __getattr__(self, attr): + def __getattribute__(self, attr): """ - Proxy other attributes to the underlying HttpRequest object. + If an attribute does not exist on this instance, then we also attempt + to proxy it to the underlying HttpRequest object. """ - return getattr(self._request, attr) + try: + return super(Request, self).__getattribute__(attr) + except AttributeError: + info = sys.exc_info() + try: + return getattr(self._request, attr) + except AttributeError: + raise info[0], info[1], info[2].tb_next -- cgit v1.2.3 From 54d82f59ed8a5d2ad4c679680dc52b8a94831d50 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 9 Feb 2015 17:19:22 +0000 Subject: Py3 compat fix --- rest_framework/request.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'rest_framework') diff --git a/rest_framework/request.py b/rest_framework/request.py index 38fcf9c0..c4de9424 100644 --- a/rest_framework/request.py +++ b/rest_framework/request.py @@ -12,9 +12,9 @@ from __future__ import unicode_literals from django.conf import settings from django.http import QueryDict from django.http.multipartparser import parse_header +from django.utils import six from django.utils.datastructures import MultiValueDict from django.utils.datastructures import MergeDict as DjangoMergeDict -from django.utils.six import BytesIO from rest_framework import HTTP_HEADER_ENCODING from rest_framework import exceptions from rest_framework.settings import api_settings @@ -363,7 +363,7 @@ class Request(object): elif hasattr(self._request, 'read'): self._stream = self._request else: - self._stream = BytesIO(self.raw_post_data) + self._stream = six.BytesIO(self.raw_post_data) def _perform_form_overloading(self): """ @@ -405,7 +405,7 @@ class Request(object): self._CONTENTTYPE_PARAM in self._data ): self._content_type = self._data[self._CONTENTTYPE_PARAM] - self._stream = BytesIO(self._data[self._CONTENT_PARAM].encode(self.parser_context['encoding'])) + self._stream = six.BytesIO(self._data[self._CONTENT_PARAM].encode(self.parser_context['encoding'])) self._data, self._files, self._full_data = (Empty, Empty, Empty) def _parse(self): @@ -498,4 +498,4 @@ class Request(object): try: return getattr(self._request, attr) except AttributeError: - raise info[0], info[1], info[2].tb_next + six.reraise(info[0], info[1], info[2].tb_next) -- cgit v1.2.3 From b2939c157d32e604e10099be891e382d8c54bbec Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 9 Feb 2015 17:43:20 +0000 Subject: Fixes for latest version of pep8 --- rest_framework/templatetags/rest_framework.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'rest_framework') diff --git a/rest_framework/templatetags/rest_framework.py b/rest_framework/templatetags/rest_framework.py index 69e03af4..d66ffb33 100644 --- a/rest_framework/templatetags/rest_framework.py +++ b/rest_framework/templatetags/rest_framework.py @@ -154,7 +154,9 @@ def urlize_quoted_links(text, trim_url_limit=None, nofollow=True, autoescape=Tru If autoescape is True, the link text and URLs will get autoescaped. """ - trim_url = lambda x, limit=trim_url_limit: limit is not None and (len(x) > limit and ('%s...' % x[:max(0, limit - 3)])) or x + def trim_url(x, limit=trim_url_limit): + return limit is not None and (len(x) > limit and ('%s...' % x[:max(0, limit - 3)])) or x + safe_input = isinstance(text, SafeData) words = word_split_re.split(force_text(text)) for i, word in enumerate(words): -- cgit v1.2.3