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