0

我想捕获我在从 base.html 调用的方法中引发的自定义异常。发生这种情况时,我需要将用户重定向到另一个页面。最好的地方在哪里?

下面是显示问题的简化代码示例

base.html:

{% if something %}{{ widget_provider.get_header }}{% endif %}

widget_providers.py

class SpecificWidgetProvider(BaseWidgetProvider):
    def get_header(self):
        if self.user.is_anonimous():
            raise AuthenticationRequired()
        return third_party_api.get_top_secret_header_widget()

AuthenticationRequired 异常可能由我的站点的许多部分(大多数时间在视图中)引发,我想将处理程序保留在一个地方。所以我创建了一个中间件来捕获这种类型的异常。

中间件.py

def process_exception(request, exception):
    if isinstance(exception, AuthenticationRequired):
        return redirect('accounts:login')

但我发现基于类的视图可能会将模板渲染阶段留到以后。它们只是返回 TemplateResponse 实例,并且 Django 的请求处理程序(django.core.handlers.base 中的 get_response())在所有中间件堆栈之外调用 response.render()。所以现在我的中间件无法捕捉到异常。也许从上下文处理器调用 get_header() 会更好,但这也无济于事。

4

1 回答 1

0

我通过在同一个中间件的 process_template_response() 中预取 try/except 中的数据解决了这个问题,并将错误处理移至公共私有方法。这使我可以将错误处理保持在同一个地方。

def process_template_response(self, request, response)
    try:
        widget_provider.get_header()
    except AuthenticationRequired:
        response = self._process_auth_required()
        # Bind render() method that just returns itself, because we must
        # return TemplateResponse or similar here.
        def render(self):
            return self
        response.render = types.MethodType(render, response)
        return response

def process_exception(self, request, exception):
    if isinstance(exception, AuthenticationRequired):
        return self._process_auth_required()

def _process_auth_required(self):
    return redirect('accounts:login')
于 2012-09-10T21:08:59.390 回答