当 PermissionDenied 异常引发时,Django 打印错误

Django prints error when PermissionDenied exception raises

在我们的项目中,我们使用了 django SessionMiddleware 来处理用户会话并且它工作正常。这里唯一的问题是当 PermissionDenied 异常发生时,错误及其回溯将在控制台中打印出来!然而正如预期的那样,通过引发该异常,403 页面将显示给用户,但我认为这似乎不合理,因为这里的中间件正在处理异常!就像未发现异常一样,我希望控制台中没有错误。有什么问题吗?!

这里是中间件设置:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django_otp.middleware.OTPMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'axes.middleware.AxesMiddleware',
]

这是打印的错误:

Forbidden (Permission denied): /the/not_allowed/page
Traceback (most recent call last):
  File "/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/lib/python3.8/contextlib.py", line 75, in inner
    return func(*args, **kwds)
  File "/our_project/base/decorators.py", line 88, in wrapper
    return view_func(request, *args, **kwargs)
  File "/venv/lib/python3.8/site-packages/django/contrib/auth/decorators.py", line 21, in _wrapped_view
    return view_func(request, *args, **kwargs)
  File "/venv/lib/python3.8/site-packages/django/contrib/auth/decorators.py", line 20, in _wrapped_view
    if test_func(request.user):
  File "/venv/lib/python3.8/site-packages/django/contrib/auth/decorators.py", line 70, in check_perms
    raise PermissionDenied
django.core.exceptions.PermissionDenied

由此

In this example the exception is raised from permission_required decorator in django.contrib.auth.decorators. I passed raise_exception=True to this decorator to make it raise exception instead of redirecting to login page

所以,很明显你在装饰器中设置了raise_exception=True

来自 doc

If the raise_exception parameter is given, the decorator will raise PermissionDenied, prompting the 403 (HTTP Forbidden) view instead of redirecting to the login page.

所以,从技术上讲,当条件不满足时,Django 会抛出异常。但是,根据 403.html 的值,Django 将向您显示 plain 403 pagecustom HTML 回应.


I expect no error in the console. Is there anything wrong?

这里没有问题(或者我什么都看不到)。

所以,如果你想从控制台省略回溯,你可能需要写一个错误处理中间件来处理这个异常。

# error handling middleware
from django.core.exceptions import PermissionDenied
from django.shortcuts import render


class PermissionDeniedErrorHandler:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        return response

    <b>def process_exception(self, request, exception):
        # This is the method that responsible for the safe-exception handling
        if isinstance(exception, PermissionDenied):
            return render(
                request=request,
                template_name="your_custom_403.html",
                status=403
            )
        return None</b>

注意:不要忘记在你的MIDDLEWARE[=54=中绑定这个中间件] 设置。

因此,您不会在控制台中收到任何错误回溯。

干杯!!!