处理基于类的视图的get_context_data中引发的异常

时间:2016-03-20 12:35:59

标签: python django exception-handling

我有一个基于类视图的应用程序。每个视图都继承自前面定义的基本视图。

所述视图(及其所有后代)实现了get_context_data方法,该方法可以在某些条件下抛出异常。

我想捕获这些异常并呈现特定模板。

基本上,views.py看起来像这样

class BaseView(TemplateView):
    def get_context_data(**ctx):
        context = super(BaseView, self).get_context_data(**ctx)
        if condition:
            raise CustomException('Condition was met')
        # code that adds values into context dictionary
        # like context['somevar'] = somevalue
        ...

        return context

class SpecificView1(BaseView):
    def get_context_data(**ctx):
        context = super(SpecificView1, self).get_context_data(**ctx)
        # code that updates values in context dictionary
        ...
        return context

我尝试在视图层次结构中插入新类(将BaseView重命名为OriginalBaseView

class BaseView(OriginalBaseView):
    def get_context_data(**ctx):
    context = {}
    try:
        context = super(BaseView, self).get_context_data(**ctx)
    except RepoException:
       self.template_name = 'specific_template.html'
    return context

但是使用这种方法意味着我必须更新所有后代get_context_data方法,并检查他们更新的密钥是否在context

有没有办法更好地处理这个?

2 个答案:

答案 0 :(得分:3)

您可以编写自己的中间件来处理RepoException并渲染specific_template.html

https://docs.djangoproject.com/en/1.9/topics/http/middleware/#process_exception

通过这种方式,您可以在视图中的任何位置投放RepoException,您的模板将自动呈现。

答案 1 :(得分:2)

batiskaf答案似乎是正确的。您基本上需要放置一个处理视图异常的中间件。这个中间件可以发送无处理,在这种情况下处理异常,或者发送HTTP响应,可以将你的template.html渲染。

    def process_exception(exception, *args, **kwargs):
        error_code = getattr(exception, 'code', 500) #you can use codes if you want
        if not isinstance(exception, MyBaseException):
        request = kwargs.get('request') #you can use request to load the template
     return {
          'status': 0,
          'message': exception.message,
          'error_code': error_code
     } #or send an HttpResponse with your template.

希望这会有所帮助:)