mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-23 10:03:57 +03:00
52 lines
1.7 KiB
Python
52 lines
1.7 KiB
Python
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):
|
|
"""
|
|
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
|
|
"""
|
|
allowed_methods = [method.upper() for method in allowed_methods]
|
|
|
|
def decorator(func):
|
|
@wraps(func, assigned=available_attrs(func))
|
|
def inner(request, *args, **kwargs):
|
|
try:
|
|
|
|
request = Request(request)
|
|
|
|
if request.method not in allowed_methods:
|
|
raise exceptions.MethodNotAllowed(request.method)
|
|
|
|
response = func(request, *args, **kwargs)
|
|
|
|
if isinstance(response, Response):
|
|
response.request = request
|
|
|
|
return response
|
|
|
|
except exceptions.APIException as exc:
|
|
return Response({'detail': exc.detail}, status=exc.status_code)
|
|
|
|
except Http404 as exc:
|
|
return Response({'detail': 'Not found'},
|
|
status=status.HTTP_404_NOT_FOUND)
|
|
|
|
except PermissionDenied as exc:
|
|
return Response({'detail': 'Permission denied'},
|
|
status=status.HTTP_403_FORBIDDEN)
|
|
return inner
|
|
return decorator
|