捕获受保护的错误并向用户显示其消息,而不是裸露的500代码

Mic*_*ael 2 django

Django 1.11

我正在建立照片档案。通过AJAX,我向框架中添加了一些信息(注释,注释,位置等)。

但是现在我要组织删除框架。

这似乎是我设法找到的一个相关问题:处理Django DeleteView中的PROTECT ERROR

我需要通知用户:您正在尝试从其他物体的脚下割草。

贝里斯拉夫·洛帕克(Berislav Lopac)在上述链接上的回答似乎是合理的。

现在在生产服务器上,我得到了:

服务器错误(500)

在调试模式下,我可以看到ProtectedError。

您能否帮助我了解如何在生产中向用户显示有意义的信息?只需捕获ProtectedError消息并显示它即可,而不是Server Error(500)。

楷模

class Frame(models.Model):

    type = models.CharField(max_length=10,
                            blank=False,
                            null=False,
                            default="---",
                            verbose_name=_('type'))


class FramePlace(CommonUrlMethodsMixin,
                models.Model
                ):

    frame = models.ForeignKey(Frame,
                              blank=False,
                              on_delete=models.PROTECT,
                              verbose_name=_("frame"))

    place = models.ForeignKey(Place,
                              blank=False,
                              on_delete=models.PROTECT,
                              verbose_name=_("place"))
Run Code Online (Sandbox Code Playgroud)

Nou*_*olf 5

有两种方法可以实现此目的

  1. 覆盖所需ViewSet 的perform_destroydestroy方法
  2. 添加中间件以处理所有ViewSet的异常

1-ViewSet级别(特定)

class MyViewSet(viewsets.ModelViewSet):
    def perform_destroy(self, instance):
        try:
            return super(MyViewSet, self).perform_destroy(instance)
        except ProtectedError as exception:
            data = {
                'code': 'server_error',
                'message': _('Internal server error.'),
                'error': {
                    'type': str(type(exception)),
                    'message': str(exception)
                }
            }
            return JsonResponse(data=data, status=status.HTTP_400_BAD_REQUEST)
Run Code Online (Sandbox Code Playgroud)

2-应用程序级别(常规)

中间件

class ExceptionMiddleware(object):
    """
    Middleware that makes sure clients see a meaningful error message wrapped in a Json response.
    """    
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response

    def process_exception(self, request, exception):
        data = {
            'code': 'server_error',
            'message': _('Internal server error.'),
            'error': {
                'type': str(type(exception)),
                'message': str(exception)
            }
        }
        return JsonResponse(data=data, status=status.HTTP_400_BAD_REQUEST)
Run Code Online (Sandbox Code Playgroud)

settings.py

MIDDLEWARE = [
    ...
    'myapp.middleware.ExceptionMiddleware'
]
Run Code Online (Sandbox Code Playgroud)