我有一个基于类视图的应用程序。每个视图都继承自前面定义的基本视图。
所述视图(及其所有后代)实现了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
。
有没有办法更好地处理这个?
答案 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.
希望这会有所帮助:)