1

我在 Django Rest Framework 中有此 UserDetailsView 代码。我正在使用 django 1.9 和 DRF 3。

class UserDetailsView(RetrieveUpdateAPIView):
    """
    API endpoint that allows a user to be viewed or edited.
    """
    serializer_class = UserDetailsSerializer
    permission_classes = (IsAuthenticated,)

    def get_object(self):
        pk = self.kwargs.get('pk', None)
        if not pk or (pk == str(self.request.user.pk)):
            return self.request.user
        else:
            try:
                return get_object_or_404(User, id=pk)
            except ValueError:
                return get_object_or_404(User, username=pk) 

我已经根据这些设置配置了我的 django 记录器。

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'simple': {
            'format': '[%(levelname)s]  %(message)s'
        },
    },
    'handlers': {
        'default': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'logs/backend_common.log',
            'maxBytes': 1024*1024*10,
            'backupCount': 10,
            'formatter': 'simple',
        },
        'request_handler': {
            'level': 'DEBUG',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'logs/backend_requests.log',
            'maxBytes': 1024*1024*10,
            'backupCount': 10,
            'formatter': 'simple',
        },
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
        }
    },
    'loggers': {
        '': {
            'handlers': ['default'],
            'propagate': True,
        },
        'django.request': {
            'handlers': ['request_handler', 'mail_admins'],
            'level': 'DEBUG',
            'propagate': False,
        }
    }
}

现在,理想情况下,所有 django 4xx、5xx 错误状态代码都应该记录到 backend_requests.log 文件中,并且除了 get_object_or_404 产生的 404 状态之外。我认为这个视图导致的 404 错误也应该被记录下来。非常感谢任何帮助。

4

1 回答 1

1

这里实际上有两个问题。

第一个是 Django 中的一个错误,几天前才修复。记录 404 的代码运行得有点太早了。Django 的下一个版本将正常工作,并且您的 404 将按照您的预期记录。

然而,对于其他例外情况,问题如下。如果导致它们的异常被冒泡到核心请求处理程序, Django 将记录错误。但是,如果视图或某些中间件捕获异常并处理它,那么这部分 Django 代码永远不会被调用。这就是DRF正在发生的事情:

REST 框架的视图处理各种异常,并处理返回适当的错误响应。

处理的异常是:

  • APIException在 REST 框架内提出的子类。
  • Django 的Http404例外。
  • Django 的PermissionDenied例外。

在每种情况下,REST 框架都会返回一个带有适当状态代码和 content-type 的响应。响应的正文将包含有关错误性质的任何其他详细信息。

因为 DRF 捕获异常并向 Django 返回一个响应对象,所以 Django 将只呈现响应而不记录错误。这是有道理的 - 一些中间件可能会采用最初的 404 但返回不同的响应(flatpage中间件是一个很好的例子)。

如果你想记录 DRF 处理的异常,你可以EXCEPTION_HANDLER在 DRF 配置中指定你自己的,或者编写你自己的中间件来记录错误。

请注意,DRF 不处理 5xx 异常,这些异常仍应传播到 Django。即使是现在,这些也应该为您记录下来。

于 2016-05-02T04:39:27.817 回答