mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-02-03 05:04:31 +03:00
Move logic for attaching HTTP handlers into LazyViewCreator
This commit is contained in:
parent
21b1116af5
commit
f6488cb058
|
@ -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()
|
||||
if isinstance(func_or_instance, LazyViewCreator):
|
||||
return func_or_instance
|
||||
return LazyViewCreator(func_or_instance)
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
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')
|
||||
|
|
Loading…
Reference in New Issue
Block a user