【问题标题】:Include request data in Django Rest Framework custom exception handler response data在 Django Rest Framework 自定义异常处理程序响应数据中包含请求数据
【发布时间】:2015-08-27 10:41:20
【问题描述】:

使用的技术:

http://www.django-rest-framework.org

例外情况: http://www.django-rest-framework.org/api-guide/exceptions/

在自定义 exceptions.py 文件中包含 rest_framework 默认示例:

from rest_framework.views import exception_handler

import sys

def custom_exception_handler(exc, context=None):

    # Call REST framework's default exception handler first,
    # to get the standard error response.
    response = exception_handler(exc)

    # Now add the HTTP status code to the response and rename detail to error
    if response is not None:
        response.data['status_code'] = response.status_code
        response.data['request'] = request
        response.data['error'] = response.data.get('detail')
        del response.data['detail']

    return response

这会发送“Http404”等基本错误信息,但不会发送请求数据,例如 IP 地址等。

将我的请求添加到响应中的最佳方式是什么?提前致谢。

更新(并已解决):

因此,我最初尝试使用 DjangoRestFramework 2.4.x 解决此问题,但该版本没有自定义异常处理程序的请求或上下文数据选项。升级到 3.1.3 可以轻松地将数据添加到响应中。新代码现在看起来像这样(使用版本 3.1.3):

def custom_exception_handler(exc, request):

# Call REST framework's default exception handler first,
# to get the standard error response.
response = exception_handler(exc, request)

# Send error to rollbar
rollbar.report_exc_info(sys.exc_info(), request)

# Now add the HTTP status code to the response and rename detail to error
if response is not None:
    response.data['status_code'] = response.status_code
    response.data['error'] = response.data.get('detail')
    del response.data['detail']

return response

【问题讨论】:

  • 请检查response = exception_handler(exc)的缩进。对吗?
  • 谢谢拉胡尔 - 是的,它是正确的 - 我在这里粘贴的方式看起来不对

标签: python django error-handling django-rest-framework django-errors


【解决方案1】:

这应该适用于您的情况。

from rest_framework.views import exception_handler

import sys

def custom_exception_handler(exc, context=None):

    # Call REST framework's default exception handler first,
    # to get the standard error response.
    response = exception_handler(exc)

    # Now add the HTTP status code to the response and rename detail to error
    if response is not None:
        response.data['status_code'] = response.status_code
        response.data['request'] = context['request']
        response.data['error'] = response.data.get('detail')
        del response.data['detail']

    return response

您可以从传递给custom_exception_handler 的上下文中访问request。这是在 DRF 3.1.0 中添加的。另请参阅此issue 已解决的问题。

如果您使用的是 DRFrequest。您可以升级到 DRF 3.1.3(PyPI 中的最新版本),然后在上下文中轻松访问 request

取自 DRF 3.1.1 源代码:

def get_exception_handler_context(self):
    """
    Returns a dict that is passed through to EXCEPTION_HANDLER,
    as the `context` argument.
    """
    return {
        'view': self,
        'args': getattr(self, 'args', ()),
        'kwargs': getattr(self, 'kwargs', {}),
        'request': getattr(self, 'request', None)
    }

另外,您需要在settings.py 文件中配置异常处理程序。

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
}

如果未指定,'EXCEPTION_HANDLER' 设置默认为 REST 框架提供的标准异常处理程序:

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'
}

注意:

异常处理程序只会被调用生成的响应 引发异常。它不会用于返回的任何响应 直接由视图,例如 HTTP_400_BAD_REQUEST 响应 当序列化验证失败时由通用视图返回。

【讨论】:

  • 谢谢拉胡尔 - 我实际上已经有了,但需要定义请求......
  • 嗨 Rahul - 是的,我已经将异常处理程序添加到我的 settings.py 文件中了 - 但仍然无法获取该信息...感谢 agian 的帮助
  • 如果可行,请尝试通过context['request'] 访问request
  • 我得到 'NoneType' 对象不可下标
  • 尝试在您的代码中将ipdb 之类的调试器放入custom_handler_exception 中,看看您在context 中得到了什么。
猜你喜欢
  • 1970-01-01
  • 2015-12-19
  • 1970-01-01
  • 2016-12-29
  • 1970-01-01
  • 2016-09-08
  • 2023-03-26
  • 2020-06-10
  • 2012-04-30
相关资源
最近更新 更多