我有一个ViewSet:
...
from handlers import specific_exception_handler...
...
class SomeViewSet(GenericViewSet):
"""
Some custom generic viewset
"""
queryset = SomeModel.objects.all()
serializer_class = SomeSerializer
parser_classes = (ParserClassThatReadSpecificXML,)
renderer_classes = (RendererClassThatConvertResponseIntoSpecificXML,)
def get_exception_handler(self):
return specific_exception_handler_function_that_return_specific_xml_format_error
@action(methods=['post'], detail=False, url_path='some_url', url_name='some_url')
def register(self, request, format=None):
some_variable = request.data.get('some_value', None)
if not some_variable:
raise ValueError
return Response(data=some_variable, content_type="text/xml; charset=shift_jis")
我有一个渲染器:...
import xmltodict
class RendererClassThatConvertResponseIntoSpecificXML(BaseRenderer):
media_type = 'text/xml'
format = 'txt'
charset = 'shift_jis'
def render(self, data, media_type=None, renderer_context=None):
# return data as non utf-8 xml string
return xmltodict.unparse(data).encode("shift_jis")
我有一个自定义错误处理程序:...
from rest_framework.views import exception_handler
def specific_exception_handler_function_that_return_specific_xml_format_error(exc, context):
response = exception_handler(exc, context)
if response is not None:
status_code = response.status_code
else:
status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
specific_data_that_will_be_converted_into_xml_by_render = {'ERROR_STATUS': status_code}
headers = {'Retry-After': '300'}
return Response(data, content_type='text/xml; charset=shift_jis', status=status_code, headers=headers)
问题:如果将引发View的
raise ValueError
,我会收到我的自定义XML格式的错误消息。500 Server Error
消息404 Server Error
消息我想随时显示我的自定义XML错误。
我该怎么做?
最佳答案
好的,这里还是没有答案,所以我会尝试自己回答
我最终是怎么做到的:
...
from rest_framework.views import exception_handler
from rest_framework import status
from django.http import HttpResponse
...
# ex-specific_exception_handler_function_that_return_specific_xml_format_error
def inside_view_occurred_error_handler(exc, context):
if isinstance(exc, rest_framework.exceptions.NotAuthenticated):
# do custom action for NotAuthenticated
elif isinstance(exc, rest_framework.exceptions.PermissionDenied):
# do custom action for PermissionDenied
elif ...
# do actions for other drf errors if needed
# set status (for example 500)
status = status.HTTP_500_INTERNAL_SERVER_ERROR
# set body
body='<?xml version="1.0" encoding="shift_jis"?><a attr="error">エラー</a>'.encode('shift_jis')
# create response
r = HttpResponse(body, status=status, content_type='text/xml; charset=shift_jis')
# add headers
r['Retry-After'] = '3000'
return r
def outside_view_400_error_handler(request, exception):
# set status
status = status.HTTP_400_BAD_REQUEST
# set body
body='<?xml version="1.0" encoding="shift_jis"?><a attr="error_400">エラー400</a>'.encode('shift_jis')
# create response
r = HttpResponse(body, status=status, content_type='text/xml; charset=shift_jis')
# add headers
r['Retry-After'] = '3000'
return r
def outside_view_500_error_handler(request):
# set status
status = status.HTTP_500_INTERNAL_SERVER_ERROR
# set body
body='<?xml version="1.0" encoding="shift_jis"?><a attr="error_500">エラー500</a>'.encode('shift_jis')
# create response
r = HttpResponse(body, status=status, content_type='text/xml; charset=shift_jis')
# add headers
r['Retry-After'] = '3000'
return r
def outside_view_404_error_handler(request, exception):
# set status
status = status.HTTP_404_NOT_FOUND
# here is no body
# create response
r = HttpResponse(status=status, content_type='text/xml; charset=shift_jis')
return r
handler400 = 'application.handlers.outside_view_400_error_handler'
handler404 = 'application.handlers.outside_view_404_error_handler'
handler500 = 'application.handlers.outside_view_500_error_handler'
现在,如果DEBUG = False
Django随时使用自定义响应进行响应。
关于python - 如何在Django和Django Rest框架中覆盖/自定义所有服务器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62948384/