aboutsummaryrefslogtreecommitdiffstats
path: root/djangorestframework
diff options
context:
space:
mode:
Diffstat (limited to 'djangorestframework')
-rw-r--r--djangorestframework/decorators.py51
1 files changed, 19 insertions, 32 deletions
diff --git a/djangorestframework/decorators.py b/djangorestframework/decorators.py
index 22bb8d3e..ac976bec 100644
--- a/djangorestframework/decorators.py
+++ b/djangorestframework/decorators.py
@@ -16,11 +16,14 @@ class LazyViewCreator(object):
This is done so that the ordering of stacked decorators is irrelevant.
"""
- def __init__(self):
+ def __init__(self, wrapped_view):
+
+ self.wrapped_view = wrapped_view
# Each item in this dictionary will be copied onto the final
# class-based view that gets created when this object is called
self.final_view_attrs = {
+ 'http_method_names': APIView.http_method_names,
'renderer_classes': APIView.renderer_classes,
'parser_classes': APIView.parser_classes,
'authentication_classes': APIView.authentication_classes,
@@ -29,6 +32,9 @@ class LazyViewCreator(object):
}
self._cached_view = None
+ def handler(self, *args, **kwargs):
+ return self.wrapped_view(*args, **kwargs)
+
@property
def view(self):
"""
@@ -44,6 +50,11 @@ class LazyViewCreator(object):
for attr, value in self.final_view_attrs.items():
setattr(WrappedAPIView, attr, value)
+ # Attach the wrapped view function for each of the
+ # allowed HTTP methods
+ for method in WrappedAPIView.http_method_names:
+ setattr(WrappedAPIView, method.lower(), self.handler)
+
self._cached_view = WrappedAPIView.as_view()
return self._cached_view
@@ -55,51 +66,27 @@ class LazyViewCreator(object):
return self.view(*args, **kwargs)
@staticmethod
- def maybe_create(func):
+ def maybe_create(func_or_instance):
"""
If the argument is already an instance of LazyViewCreator,
just return it. Otherwise, create a new one.
"""
- if isinstance(func, LazyViewCreator):
- return func
- return LazyViewCreator()
-
-
-def api_view(allowed_methods):
- """
- Decorator for function based views.
-
- @api_view(['GET', 'POST'])
- def my_view(request):
- # request will be an instance of `Request`
- # `Response` objects will have .request set automatically
- # APIException instances will be handled
- """
-
- def decorator(func):
- wrapper = LazyViewCreator.maybe_create(func)
-
- @wraps(func, assigned=available_attrs(func))
- def handler(self, *args, **kwargs):
- return func(*args, **kwargs)
-
- for method in allowed_methods:
- wrapper.final_view_attrs[method.lower()] = handler
-
- return wrapper
- return decorator
+ if isinstance(func_or_instance, LazyViewCreator):
+ return func_or_instance
+ return LazyViewCreator(func_or_instance)
-def _create_attribute_setting_decorator(attribute):
+def _create_attribute_setting_decorator(attribute, filter=lambda item: item):
def decorator(value):
def inner(func):
wrapper = LazyViewCreator.maybe_create(func)
- wrapper.final_view_attrs[attribute] = value
+ wrapper.final_view_attrs[attribute] = filter(value)
return wrapper
return inner
return decorator
+api_view = _create_attribute_setting_decorator('http_method_names', filter=lambda methods: [method.lower() for method in methods])
renderer_classes = _create_attribute_setting_decorator('renderer_classes')
parser_classes = _create_attribute_setting_decorator('parser_classes')
authentication_classes = _create_attribute_setting_decorator('authentication_classes')