aboutsummaryrefslogtreecommitdiffstats
path: root/rest_framework
diff options
context:
space:
mode:
authorTom Christie2015-02-09 20:43:50 +0000
committerTom Christie2015-02-09 20:43:50 +0000
commitfbb21caaaa01033bbd34b0c63ab48243ffb6310e (patch)
tree5d0fdee18c9bf02733b1df913c4cddd9e3e86da7 /rest_framework
parent407480b4840990ff17f9a33b293cfcf15bb6f7c5 (diff)
parent7b639c0cd0676172cc8502e833f5b708f39f9a83 (diff)
downloaddjango-rest-framework-fbb21caaaa01033bbd34b0c63ab48243ffb6310e.tar.bz2
Merge master
Diffstat (limited to 'rest_framework')
-rw-r--r--rest_framework/authentication.py2
-rw-r--r--rest_framework/decorators.py11
-rw-r--r--rest_framework/pagination.py4
-rw-r--r--rest_framework/request.py21
-rw-r--r--rest_framework/response.py3
-rw-r--r--rest_framework/serializers.py6
-rw-r--r--rest_framework/templatetags/rest_framework.py4
-rw-r--r--rest_framework/throttling.py4
8 files changed, 36 insertions, 19 deletions
diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py
index a75cd30c..f0702286 100644
--- a/rest_framework/authentication.py
+++ b/rest_framework/authentication.py
@@ -168,7 +168,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.'))
diff --git a/rest_framework/decorators.py b/rest_framework/decorators.py
index 325435b3..21de1acf 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):
@@ -109,10 +108,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.
"""
+ methods = ['get'] if (methods is None) else methods
+
def decorator(func):
func.bind_to_methods = methods
func.detail = True
@@ -121,10 +122,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.
"""
+ methods = ['get'] if (methods is None) else methods
+
def decorator(func):
func.bind_to_methods = methods
func.detail = False
diff --git a/rest_framework/pagination.py b/rest_framework/pagination.py
index b3658aca..496500ba 100644
--- a/rest_framework/pagination.py
+++ b/rest_framework/pagination.py
@@ -168,7 +168,9 @@ def _reverse_ordering(ordering_tuple):
Given an order_by tuple such as `('-created', 'uuid')` reverse the
ordering and return a new tuple, eg. `('created', '-uuid')`.
"""
- invert = lambda x: x[1:] if (x.startswith('-')) else '-' + x
+ def invert(x):
+ return x[1:] if (x.startswith('-')) else '-' + x
+
return tuple([invert(item) for item in ordering_tuple])
diff --git a/rest_framework/request.py b/rest_framework/request.py
index 86fb1ef1..081ace23 100644
--- a/rest_framework/request.py
+++ b/rest_framework/request.py
@@ -12,12 +12,13 @@ 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
+import sys
import warnings
@@ -366,7 +367,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):
"""
@@ -408,7 +409,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):
@@ -489,8 +490,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:
+ six.reraise(info[0], info[1], info[2].tb_next)
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
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 7235d8c5..c60574d4 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.'
)
@@ -635,11 +635,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.
diff --git a/rest_framework/templatetags/rest_framework.py b/rest_framework/templatetags/rest_framework.py
index a969836f..699ea897 100644
--- a/rest_framework/templatetags/rest_framework.py
+++ b/rest_framework/templatetags/rest_framework.py
@@ -143,7 +143,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):
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)