我在perform_create方法中尝试了这个:
if not user.is_active:
return HttpResponseForbidden()
但没有发生错误,它仍然在回应201
答案 0 :(得分:1)
请改用此构造:
from rest_framework.exceptions import PermissionDenied
# You can also use Django's PermissionDenied here; DRF handles that nicely
from django.core.exceptions import PermissionDenied
if not user.is_active:
raise PermissionDenied
PermissionDenied
定义如下:
class PermissionDenied(APIException):
status_code = status.HTTP_403_FORBIDDEN
default_detail = _('You do not have permission to perform this action.')
default_code = 'permission_denied'
您可能想知道如何在View
内引发异常会返回相应的HttpResponse
。 DRF的APIView
有一个漂亮的handle_exception
方法,它使用exception_handler
函数(如下所示)来实现这个魔力:
def exception_handler(exc, context):
"""
Returns the response that should be used for any given exception.
By default we handle the REST framework `APIException`, and also
Django's built-in `Http404` and `PermissionDenied` exceptions.
Any unhandled exceptions may return `None`, which will cause a 500 error
to be raised.
"""
if isinstance(exc, Http404):
exc = exceptions.NotFound()
# This is how both PermissionDenied classes are made to work
elif isinstance(exc, PermissionDenied):
exc = exceptions.PermissionDenied()
if isinstance(exc, exceptions.APIException):
headers = {}
if getattr(exc, 'auth_header', None):
headers['WWW-Authenticate'] = exc.auth_header
if getattr(exc, 'wait', None):
headers['Retry-After'] = '%d' % exc.wait
if isinstance(exc.detail, (list, dict)):
data = exc.detail
else:
data = {'detail': exc.detail}
set_rollback()
return Response(data, status=exc.status_code, headers=headers)
return None
澄清:
PermissionDenied
是一个例外;您需要raise
而不是return