Django: 如何像Http404那样引发Http401和Http403异常,而不是返回RESPONSE

2024-04-28 04:25:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试使用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\u object\u或\u 404。你知道吗

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

但我试图提出的例外(与Http404完全相同)提出了以下问题: Http403


Tags: djangotokenapigetifrequestdefcheck
2条回答

这是处理异常的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

响应有handler和异常converter,允许您执行raise Http404。如您所见,它们还将PermissionDenied异常转换为带有403状态代码的响应。因此,您可以提高it而不是Http403。但是对于401你必须返回return HttpResponse('Unauthorized', status=401)类似的东西。你知道吗

相关问题 更多 >