Регистратор django.request не работает для get_object_or_404
У меня есть этот код для UserDetailsView в Django Rest Framework. Я использую 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 logger, настроенный согласно этим настройкам.
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, и они, кроме статуса 404, являются результатом get_object_or_404. Я думаю, что 404 ошибки, вытекающие из этого представления, также должны регистрироваться. Любая помощь высоко ценится.
1 ответ
Здесь на самом деле есть две проблемы.
Первая ошибка в Django, которая была исправлена всего несколько дней назад. Часть кода, которая регистрировала 404, работала слишком рано. Следующая версия Django будет работать, и ваши 404 будут зарегистрированы, как вы ожидаете.
Однако для других исключений проблема заключается в следующем. Django будет регистрировать ошибки, если вызвавшие их исключения были переданы в основной обработчик запросов. Однако если представление или какое-либо промежуточное программное обеспечение перехватывает исключение и обрабатывает его, то эта часть кода Django никогда не вызывается. Вот что происходит с DRF:
Представления платформы REST обрабатывают различные исключения и имеют дело с возвратом соответствующих ответов об ошибках.
Обработанные исключения:
- Подклассы
APIException
поднятый внутри структуры REST.- Джанго
Http404
исключение.- Джанго
PermissionDenied
исключение.В каждом случае среда REST возвращает ответ с соответствующим кодом состояния и типом содержимого. Тело ответа будет включать в себя любые дополнительные детали относительно характера ошибки.
Поскольку DRF перехватывает исключение и возвращает объект ответа Django, Django будет просто отображать ответ, а не регистрировать ошибку. Это имеет смысл - некоторые промежуточные программы могут взять то, что изначально было 404, но вместо этого вернуть другой ответ (flatpage
промежуточное программное обеспечение является хорошим примером).
Если вы хотите регистрировать исключения, обработанные DRF, вы можете указать свой собственный EXCEPTION_HANDLER
в конфигурации DRF или напишите свое собственное промежуточное программное обеспечение, которое регистрирует ошибки.
Обратите внимание, что исключения 5xx не обрабатываются DRF и должны распространяться вплоть до Django. Они должны быть зарегистрированы для вас даже сейчас.