2012-09-26 16:52:29 +04:00
|
|
|
from rest_framework.views import APIView
|
2013-01-19 19:51:14 +04:00
|
|
|
import types
|
2012-09-14 19:07:07 +04:00
|
|
|
|
|
|
|
|
2012-09-26 16:52:29 +04:00
|
|
|
def api_view(http_method_names):
|
2012-09-14 19:07:07 +04:00
|
|
|
|
|
|
|
"""
|
2012-09-26 16:52:29 +04:00
|
|
|
Decorator that converts a function-based view into an APIView subclass.
|
|
|
|
Takes a list of allowed methods for the view as an argument.
|
2012-09-14 19:07:07 +04:00
|
|
|
"""
|
|
|
|
|
2012-09-26 16:52:29 +04:00
|
|
|
def decorator(func):
|
|
|
|
|
2012-10-29 18:41:33 +04:00
|
|
|
WrappedAPIView = type(
|
|
|
|
'WrappedAPIView',
|
|
|
|
(APIView,),
|
|
|
|
{'__doc__': func.__doc__}
|
|
|
|
)
|
|
|
|
|
|
|
|
# Note, the above allows us to set the docstring.
|
2012-11-14 22:36:29 +04:00
|
|
|
# It is the equivalent of:
|
2012-10-29 18:41:33 +04:00
|
|
|
#
|
|
|
|
# class WrappedAPIView(APIView):
|
|
|
|
# pass
|
|
|
|
# WrappedAPIView.__doc__ = func.doc <--- Not possible to do this
|
2012-09-26 16:52:29 +04:00
|
|
|
|
2013-01-19 19:51:14 +04:00
|
|
|
# api_view applied without (method_names)
|
|
|
|
assert not(isinstance(http_method_names, types.FunctionType)), \
|
|
|
|
'@api_view missing list of allowed HTTP methods'
|
|
|
|
|
|
|
|
# api_view applied with eg. string instead of list of strings
|
|
|
|
assert isinstance(http_method_names, (list, tuple)), \
|
|
|
|
'@api_view expected a list of strings, recieved %s' % type(http_method_names).__name__
|
|
|
|
|
2012-10-09 15:01:17 +04:00
|
|
|
allowed_methods = set(http_method_names) | set(('options',))
|
|
|
|
WrappedAPIView.http_method_names = [method.lower() for method in allowed_methods]
|
2012-09-26 16:52:29 +04:00
|
|
|
|
|
|
|
def handler(self, *args, **kwargs):
|
|
|
|
return func(*args, **kwargs)
|
|
|
|
|
|
|
|
for method in http_method_names:
|
|
|
|
setattr(WrappedAPIView, method.lower(), handler)
|
|
|
|
|
2012-10-09 12:57:08 +04:00
|
|
|
WrappedAPIView.__name__ = func.__name__
|
|
|
|
|
2012-09-26 16:52:29 +04:00
|
|
|
WrappedAPIView.renderer_classes = getattr(func, 'renderer_classes',
|
|
|
|
APIView.renderer_classes)
|
|
|
|
|
|
|
|
WrappedAPIView.parser_classes = getattr(func, 'parser_classes',
|
|
|
|
APIView.parser_classes)
|
|
|
|
|
|
|
|
WrappedAPIView.authentication_classes = getattr(func, 'authentication_classes',
|
|
|
|
APIView.authentication_classes)
|
|
|
|
|
|
|
|
WrappedAPIView.throttle_classes = getattr(func, 'throttle_classes',
|
|
|
|
APIView.throttle_classes)
|
|
|
|
|
|
|
|
WrappedAPIView.permission_classes = getattr(func, 'permission_classes',
|
|
|
|
APIView.permission_classes)
|
|
|
|
|
|
|
|
return WrappedAPIView.as_view()
|
2012-09-03 18:57:43 +04:00
|
|
|
return decorator
|
2012-09-14 19:07:07 +04:00
|
|
|
|
|
|
|
|
2012-09-26 16:52:29 +04:00
|
|
|
def renderer_classes(renderer_classes):
|
|
|
|
def decorator(func):
|
2012-09-26 23:18:57 +04:00
|
|
|
func.renderer_classes = renderer_classes
|
2012-09-26 16:52:29 +04:00
|
|
|
return func
|
|
|
|
return decorator
|
|
|
|
|
|
|
|
|
|
|
|
def parser_classes(parser_classes):
|
|
|
|
def decorator(func):
|
2012-09-26 23:18:57 +04:00
|
|
|
func.parser_classes = parser_classes
|
2012-09-26 16:52:29 +04:00
|
|
|
return func
|
|
|
|
return decorator
|
|
|
|
|
|
|
|
|
|
|
|
def authentication_classes(authentication_classes):
|
|
|
|
def decorator(func):
|
2012-09-26 23:18:57 +04:00
|
|
|
func.authentication_classes = authentication_classes
|
2012-09-26 16:52:29 +04:00
|
|
|
return func
|
|
|
|
return decorator
|
|
|
|
|
|
|
|
|
|
|
|
def throttle_classes(throttle_classes):
|
|
|
|
def decorator(func):
|
2012-09-26 23:18:57 +04:00
|
|
|
func.throttle_classes = throttle_classes
|
2012-09-26 16:52:29 +04:00
|
|
|
return func
|
|
|
|
return decorator
|
|
|
|
|
|
|
|
|
|
|
|
def permission_classes(permission_classes):
|
|
|
|
def decorator(func):
|
2012-09-26 23:18:57 +04:00
|
|
|
func.permission_classes = permission_classes
|
2012-09-26 16:52:29 +04:00
|
|
|
return func
|
|
|
|
return decorator
|