django-rest-framework/djangorestframework/decorators.py

52 lines
1.7 KiB
Python
Raw Normal View History

2012-09-03 18:57:43 +04:00
from functools import wraps
from django.http import Http404
from django.utils.decorators import available_attrs
from django.core.exceptions import PermissionDenied
from djangorestframework import exceptions
from djangorestframework import status
from djangorestframework.response import Response
from djangorestframework.request import Request
def api_view(allowed_methods):
"""
2012-09-04 15:02:05 +04:00
Decorator for function based views.
2012-09-03 18:57:43 +04:00
@api_view(['GET', 'POST'])
def my_view(request):
# request will be an instance of `Request`
2012-09-04 15:02:05 +04:00
# `Response` objects will have .request set automatically
2012-09-03 18:57:43 +04:00
# APIException instances will be handled
"""
allowed_methods = [method.upper() for method in allowed_methods]
def decorator(func):
@wraps(func, assigned=available_attrs(func))
def inner(request, *args, **kwargs):
try:
2012-09-04 15:02:05 +04:00
2012-09-03 18:57:43 +04:00
request = Request(request)
2012-09-04 15:02:05 +04:00
2012-09-03 18:57:43 +04:00
if request.method not in allowed_methods:
2012-09-04 15:02:05 +04:00
raise exceptions.MethodNotAllowed(request.method)
2012-09-03 18:57:43 +04:00
response = func(request, *args, **kwargs)
2012-09-04 15:02:05 +04:00
if isinstance(response, Response):
response.request = request
2012-09-03 18:57:43 +04:00
return response
2012-09-04 15:02:05 +04:00
2012-09-03 18:57:43 +04:00
except exceptions.APIException as exc:
return Response({'detail': exc.detail}, status=exc.status_code)
2012-09-04 15:02:05 +04:00
2012-09-03 18:57:43 +04:00
except Http404 as exc:
return Response({'detail': 'Not found'},
status=status.HTTP_404_NOT_FOUND)
2012-09-04 15:02:05 +04:00
2012-09-03 18:57:43 +04:00
except PermissionDenied as exc:
return Response({'detail': 'Permission denied'},
status=status.HTTP_403_FORBIDDEN)
return inner
return decorator