diff options
Diffstat (limited to 'rest_framework')
| -rw-r--r-- | rest_framework/__init__.py | 2 | ||||
| -rw-r--r-- | rest_framework/authentication.py | 2 | ||||
| -rw-r--r-- | rest_framework/authtoken/south_migrations/0001_initial.py | 2 | ||||
| -rw-r--r-- | rest_framework/decorators.py | 11 | ||||
| -rw-r--r-- | rest_framework/relations.py | 5 | ||||
| -rw-r--r-- | rest_framework/response.py | 3 | ||||
| -rw-r--r-- | rest_framework/routers.py | 10 | ||||
| -rw-r--r-- | rest_framework/serializers.py | 6 | ||||
| -rw-r--r-- | rest_framework/settings.py | 11 | ||||
| -rw-r--r-- | rest_framework/throttling.py | 4 |
10 files changed, 35 insertions, 21 deletions
diff --git a/rest_framework/__init__.py b/rest_framework/__init__.py index fdcebb7b..57e5421b 100644 --- a/rest_framework/__init__.py +++ b/rest_framework/__init__.py @@ -8,7 +8,7 @@ ______ _____ _____ _____ __ """ __title__ = 'Django REST framework' -__version__ = '3.0.3' +__version__ = '3.0.4' __author__ = 'Tom Christie' __license__ = 'BSD 2-Clause' __copyright__ = 'Copyright 2011-2015 Tom Christie' 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') diff --git a/rest_framework/authtoken/south_migrations/0001_initial.py b/rest_framework/authtoken/south_migrations/0001_initial.py index 926de02b..5b927f3e 100644 --- a/rest_framework/authtoken/south_migrations/0001_initial.py +++ b/rest_framework/authtoken/south_migrations/0001_initial.py @@ -40,7 +40,7 @@ class Migration(SchemaMigration): 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) }, "%s.%s" % (User._meta.app_label, User._meta.module_name): { - 'Meta': {'object_name': User._meta.module_name}, + 'Meta': {'object_name': User._meta.module_name, 'db_table': repr(User._meta.db_table)}, }, 'authtoken.token': { 'Meta': {'object_name': '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/relations.py b/rest_framework/relations.py index aa0c2def..13793f37 100644 --- a/rest_framework/relations.py +++ b/rest_framework/relations.py @@ -338,7 +338,12 @@ class ManyRelatedField(Field): # We override the default field access in order to support # lists in HTML forms. if html.is_html_input(dictionary): + # Don't return [] if the update is partial + if self.field_name not in dictionary: + if getattr(self.root, 'partial', False): + return empty return dictionary.getlist(self.field_name) + return dictionary.get(self.field_name, empty) def to_internal_value(self, data): 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/routers.py b/rest_framework/routers.py index 827da034..6a4184e2 100644 --- a/rest_framework/routers.py +++ b/rest_framework/routers.py @@ -130,19 +130,13 @@ class SimpleRouter(BaseRouter): If `base_name` is not specified, attempt to automatically determine it from the viewset. """ - # Note that `.model` attribute on views is deprecated, although we - # enforce the deprecation on the view `get_serializer_class()` and - # `get_queryset()` methods, rather than here. - model_cls = getattr(viewset, 'model', None) queryset = getattr(viewset, 'queryset', None) - if model_cls is None and queryset is not None: - model_cls = queryset.model - assert model_cls, '`base_name` argument not specified, and could ' \ + assert queryset is not None, '`base_name` argument not specified, and could ' \ 'not automatically determine the name from the viewset, as ' \ 'it does not have a `.queryset` attribute.' - return model_cls._meta.object_name.lower() + return queryset.model._meta.object_name.lower() def get_routes(self, viewset): """ diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py index 42d1e370..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.' ) @@ -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. diff --git a/rest_framework/settings.py b/rest_framework/settings.py index fc6dfecd..e5e5edaf 100644 --- a/rest_framework/settings.py +++ b/rest_framework/settings.py @@ -18,6 +18,7 @@ REST framework settings, checking for user settings first, then falling back to the defaults. """ from __future__ import unicode_literals +from django.test.signals import setting_changed from django.conf import settings from django.utils import importlib, six from rest_framework import ISO_8601 @@ -198,3 +199,13 @@ class APISettings(object): api_settings = APISettings(USER_SETTINGS, DEFAULTS, IMPORT_STRINGS) + + +def reload_api_settings(*args, **kwargs): + global api_settings + setting, value = kwargs['setting'], kwargs['value'] + if setting == 'REST_FRAMEWORK': + api_settings = APISettings(value, DEFAULTS, IMPORT_STRINGS) + + +setting_changed.connect(reload_api_settings) 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) |
