Я использую Python 3.6 с Django 1.11.9 и rest_framework 3.6.2.

У меня есть представление (APIView), к которому могут обращаться только некоторые пользователи, которые успешно прошли данную проверку HasUnlimitedAccesPermission. В случае неудачи прохождения последнего, я поднимаю PermissionDenied с подробным сообщением моего выбора об ошибке, чтобы передать на передний конец. Пока все хорошо, всего этого легко достичь, применив к моему представлению HasUnlimitedAccessPermission, благодаря декоратору license_classes (да, здесь я использую представление на основе function_based).

Теперь я хотел бы передать дополнительный атрибут в мой ответ об ошибке JSON (когда пользователь не проходит тест на разрешение). Этот атрибут будет атрибутом «error_id», который даст разработчику внешнего интерфейса возможность адаптировать отображение ошибок в зависимости от значения «error_id». Примером ответа JSON будет:

{
    "error": "To enjoy this feature, go pick one of our pay offer!",
    "error_id": "no_unlimited_access"
}

Есть идеи, как этого добиться?

0
Watchoutman 21 Авг 2018 в 12:14

3 ответа

Лучший ответ

Хорошо, благодаря комментарию Bear Brown и ответу Jerin Peter George (дополненному исходным кодом rest_framework) я сделал следующее:

1) Создано пользовательское исключение PermissionDenied:

class CustomPermissionDenied(PermissionDenied):

    def __init__(self, detail=None, code=None, error_id=None):
        super().__init__(detail=detail, code=code)
        self.error_id = error_id

Который вызывается в HasUnlimitedAccessPermission, например, так:

raise CustomPermissionDenied(detail=_("To use this feature, subscribe to one of our plans."),
                             error_id="no_unlimited_access")

2) В custom_exception_handler (который у меня уже был для других целей) я добавил строки между эллипсами

def custom_exception_handler(exc, context):
    ...
    error_id = getattr(exc, "error_id", None)
    if error_id is not None:
        new_response_data["error_id"] = error_id
    ...
    response.data = new_response_data

return response

И вот, у меня есть формат ответа об ошибке, который я искал. Спасибо всем за помощь!

0
Watchoutman 22 Авг 2018 в 13:02

Определите класс Пользовательского исключения как,

from rest_framework.serializers import ValidationError
from rest_framework import status


class CustomAPIException(ValidationError):
    """
    raises API exceptions with custom messages and custom status codes
    """
    status_code = status.HTTP_400_BAD_REQUEST
    default_code = 'error'

    def __init__(self, detail, status_code=None):
        self.detail = detail
        if status_code is not None:
            self.status_code = status_code

И использовать в представлениях как,

from rest_framework import status


def my_view(request):
    if some_condition:
        error_msg = {
            "error": "To enjoy this feature, go pick one of our pay offer!",
            "error_id": "no_unlimited_access"
        }
        raise CustomAPIException(error_msg)
0
JPG 21 Авг 2018 в 09:33

Ваша проблема может быть решена с помощью промежуточного программного обеспечения.

Я бы порекомендовал вам создать собственное промежуточное ПО. Таким образом, пользовательское промежуточное ПО может помочь вам создать ответ в соответствии с вашими потребностями. Просто подключите промежуточное программное обеспечение к вашему приложению django.

Подробнее об этом вы можете прочитать в этот блог или этот блог

0
argo 21 Авг 2018 в 09:26
51945357