Django:如何引发Http401和Http403异常,例如Http404,RAISE EXCEPTION不响应

时间:2019-11-19 11:36:18

标签: python django exception

我正在尝试使用Django制作api,并且我正在验证请求标头是否包含api键,并据此引发异常,例如:

def _check_driver_authorization(request):
if request.headers.get('authorization') is not None:
    token = request.headers['authorization']
    user = Driver.objects.filter(access_token=token)
    if user.exists():
        return

    raise Http401
else:
    raise Http403

我没有找到任何人试图这样做,并且我在这里搜索了很多线程,他们都试图返回响应(渲染),我的情况是我试图中断请求并提出请求。例外。 我的灵感来自get_object_or_404。

编辑/更新: 有关更多详细信息和解释,内置的Http404异常会引发以下问题: Http404

但是我试图做出的异常(与Http404完全一样)引发了这个问题: Http403

2 个答案:

答案 0 :(得分:0)

handler和响应converter的例外,允许您执行raise Http404。如您所见,它们还将PermissionDenied异常转换为带有403状态代码的响应。因此,您可以引发 it 而不是Http403。但是对于401,您必须返回return HttpResponse('Unauthorized', status=401)这样的内容。

答案 1 :(得分:0)

这是处理您的异常的Django代码:

def response_for_exception(request, exc):
    if isinstance(exc, Http404):
        if settings.DEBUG:
            response = debug.technical_404_response(request, exc)
        else:
            response = get_exception_response(request, get_resolver(get_urlconf()), 404, exc)

    elif isinstance(exc, PermissionDenied):
        logger.warning(
            'Forbidden (Permission denied): %s', request.path,
            extra={'status_code': 403, 'request': request},
        )
        response = get_exception_response(request, get_resolver(get_urlconf()), 403, exc)

    elif isinstance(exc, MultiPartParserError):
        logger.warning(
            'Bad request (Unable to parse request body): %s', request.path,
            extra={'status_code': 400, 'request': request},
        )
        response = get_exception_response(request, get_resolver(get_urlconf()), 400, exc)

    elif isinstance(exc, SuspiciousOperation):
        if isinstance(exc, (RequestDataTooBig, TooManyFieldsSent)):
            # POST data can't be accessed again, otherwise the original
            # exception would be raised.
            request._mark_post_parse_error()

        # The request logger receives events for any problematic request
        # The security logger receives events for all SuspiciousOperations
        security_logger = logging.getLogger('django.security.%s' % exc.__class__.__name__)
        security_logger.error(
            force_text(exc),
            extra={'status_code': 400, 'request': request},
        )
        if settings.DEBUG:
            response = debug.technical_500_response(request, *sys.exc_info(), status_code=400)
        else:
            response = get_exception_response(request, get_resolver(get_urlconf()), 400, exc)

    elif isinstance(exc, SystemExit):
        # Allow sys.exit() to actually exit. See tickets #1023 and #4701
        raise

    else:
        signals.got_request_exception.send(sender=None, request=request)
        response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())

    # Force a TemplateResponse to be rendered.
    if not getattr(response, 'is_rendered', True) and callable(getattr(response, 'render', None)):
        response = response.render()

    return response

正如您在此处看到的那样,Django将处理Http404PermissionDenied异常。 Http 401响应似乎也不例外。

PermissionDenied(Http 403)异常是以下异常(类似于Http404异常):

class PermissionDenied(Exception):
    """The user did not have permission to do that"""
    pass

因此它应该与raise PermissionDenied一起使用。

Django文档: Error views