mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-27 03:54:01 +03:00
44 lines
1.7 KiB
Python
44 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 to make a view only accept particular request methods. Usage::
|
|
|
|
@api_view(['GET', 'POST'])
|
|
def my_view(request):
|
|
# request will be an instance of `Request`
|
|
# APIException instances will be handled
|
|
|
|
Note that request methods should be in uppercase.
|
|
"""
|
|
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:
|
|
return exceptions.MethodNotAllowed(request.method)
|
|
response = func(request, *args, **kwargs)
|
|
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
|