Я использую 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"
}
Есть идеи, как этого добиться?
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
И вот, у меня есть формат ответа об ошибке, который я искал. Спасибо всем за помощь!
Определите класс Пользовательского исключения как,
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)
Ваша проблема может быть решена с помощью промежуточного программного обеспечения.
Я бы порекомендовал вам создать собственное промежуточное ПО. Таким образом, пользовательское промежуточное ПО может помочь вам создать ответ в соответствии с вашими потребностями. Просто подключите промежуточное программное обеспечение к вашему приложению django.
Подробнее об этом вы можете прочитать в этот блог или этот блог
Похожие вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.