Добавить поле к исключениям DRF.PermissionDenied
Сейчас django-rest-framework's exceptions.PermissionDenied
возвращает 403 и подробное сообщение: "У вас нет разрешения на выполнение этого действия"
{"detail": "You don't have permission to perform this action."}
Я хотел бы расширить это, чтобы включить поле "причина", так что я могу сделать что-то вроде `MyException(detail="Some detail here", reason="INSUFFICIENT_TIER"). но detail, кажется, цепочка довольно далеко вверх и преобразуется в довольно многих местах. Кто-нибудь знает, как я могу легко добавить поле, которое будет возвращено в json выше?
Вот исключение DRF для справки.
class PermissionDenied(APIException):
status_code = status.HTTP_403_FORBIDDEN
default_detail = _('You do not have permission to perform this action.')
default_code = 'permission_denied'
It extends APIException:
class APIException(Exception):
"""
Base class for REST framework exceptions.
Subclasses should provide `.status_code` and `.default_detail` properties.
"""
status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
default_detail = _('A server error occurred.')
default_code = 'error'
def __init__(self, detail=None, code=None):
if detail is None:
detail = self.default_detail
if code is None:
code = self.default_code
self.detail = _get_error_details(detail, code)
def __str__(self):
return str(self.detail)
def get_codes(self):
"""
Return only the code part of the error details.
Eg. {"name": ["required"]}
"""
return _get_codes(self.detail)
def get_full_details(self):
"""
Return both the message & code parts of the error details.
Eg. {"name": [{"message": "This field is required.", "code": "required"}]}
"""
return _get_full_details(self.detail)
Вы можете создать свой собственный PermissionClass
. Для вашего случая это будет выглядеть следующим образом:
from rest_framework import permissions
class MyCustomPermissionClass(permissions.BasePermission):
def has_permission(self, request, view):
# Basically, any logic you want
if not request.user.is_authenticated():
raise PermissionDenied
Если вы хотите, чтобы MyCustomPermissionClass
был классом разрешения по умолчанию, то вам нужно настроить его в настройках: https://www.django-rest-framework.org/api-guide/permissions/#setting-the-permission-policy.
В противном случае, вам придется указать permission_classes
в каждом ViewSet
или APIView
, которые вы используете, вот так:
class ExampleView(APIView):
permission_classes = [MyCustomPermissionClass]
Другие примеры вы можете найти здесь: https://www.django-rest-framework.org/api-guide/permissions/#examples