我在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错误也应该被记录下来。任何帮助都非常感谢。
答案 0 :(得分:1)
这里实际上有两个问题。
第一个是Django中的一个错误,它是fixed just a few days ago。记录404s的代码运行有点太早了。 Django的下一个版本将正常工作,您的404将按照您的预期进行记录。
但是,对于其他例外,问题如下。如果导致它们的异常冒泡到核心请求处理程序,Django将记录错误。但是,如果视图或某些中间件捕获异常并处理它,那么Django代码的这部分永远不会被调用。 DRF发生了这种情况:
REST框架的视图处理各种异常,并处理返回适当的错误响应。
处理的例外情况是:
- REST框架内引发的
APIException
子类。- Django的
Http404
例外。- Django的
PermissionDenied
例外。在每种情况下,REST框架都将返回具有适当状态代码和内容类型的响应。回复正文将包含有关错误性质的任何其他详细信息。
因为DRF捕获异常并将响应对象返回给Django,Django将只呈现响应而不记录错误。这是有道理的 - 一些中间件可能会采用最初的404而不是返回不同的响应(flatpage
中间件就是一个很好的例子。)
如果要记录DRF处理的异常,可以在DRF配置中指定自己的EXCEPTION_HANDLER
,或编写自己的记录错误的中间件。
请注意,DRF不处理5xx异常,这些异常仍应传播到Django。即使现在也应该为您记录这些内容。