调用render()时如何获取Django模板错误的文件名和行号?

Posted

技术标签:

【中文标题】调用render()时如何获取Django模板错误的文件名和行号?【英文标题】:How to get the filename and line number of a Django template error when calling render()? 【发布时间】:2013-06-03 03:57:13 【问题描述】:

我在一个独立的工具(而不是网络应用程序)中使用 Django 模板系统,如下所示:

from django import template

try:
    tmpl = loader.get_template(my_template_path)
    context = template.Context(my_template_context)
    txt = tmpl.render(context)
except (template.TemplateSyntaxError, template.TemplateDoesNotExist), e:
    # ...

当模板包含错误时,会引发异常。如何获取错误的文件名、行号和行位置?在这种情况下,我是否应该期望从异常中获取此信息(不为浏览器呈现响应)?

我注意到TemplateSyntaxError 有一个source 属性,其值是一个包含LoaderOrigin 和一对数字的元组。 LoaderOriginname 等于文件名。这些数字似乎与错误的字符位置不同,但也许还有另一种解释方式?

TemplateDoesNotExist 似乎没有source,只有argsmessage,它们提供了无法找到的模板名称。有没有办法找到正在加载的模板标签,或者当行号不再可用时,此错误是否会在稍后阶段发生?

我确实有django.settings 有效,并且TEMPLATE_DEBUG 设置为True,如果这很重要的话。 (我相信这是在将模板渲染到网页时报告行号所必需的,并带有花哨的错误显示。)我还使用了一个简单的模板加载器,通过TEMPLATE_LOADERS 设置,尽管我认为这无关紧要。另外,我目前坚持使用 Django 1.3,因此首选兼容 1.3 的解决方案。

谢谢!

【问题讨论】:

不确定我是否可以帮助你,但如果一切都失败了,你可以检查 django-debug-toolbar 源代码以了解它如何处理错误,或者深入了解模板代码本身。每次我不得不深入研究 Django 代码时,我发现它很容易理解。 docs.djangoproject.com/en/dev/ref/templates/api/… 这是 django 提供的一种模板支持 【参考方案1】:

我相信TemplateSyntaxErrorsource 属性是您正在寻找的。 Django 代码暗示提到的数字是发生错误的行号,请参阅https://github.com/django/django/blob/1.3.7/django/views/debug.py#L153。

至于TemplateDoesNotExist,好像被忽略了,当它作为模板标签的结果出现时,见https://github.com/django/django/blob/1.3.7/django/template/loader.py#L50。

【讨论】:

谢谢!看起来我的主要问题是TemplateSyntaxError 在我的实际应用程序中没有得到source attr,即使在我打电话给我的装载机之前settings.TEMPLATE_DEBUGTrue。一种糟糕的解决方法是直接调用DebugLexerDebugParser,然后渲染节点列表,而不是使用Template 类。我会看看我能不能做得更好。 经过更多探索:它正在使用DebugParser,但在我的测试用例中,TemplateSyntaxError 是由FilterExpression.__init__() 提出的,并且在任何时候它都不会被捕获以便用@对其进行注释987654336@。我希望解析器的compile_function_error()parse() 期间被调用,但如果错误出现在过滤器表达式中,则不会发生这种情况。 (token 可用,但在这种情况下不使用它。)所以最好的情况是测试hasattr(e, 'source') 并仅在找到时使用它。 @Dan:我预计compile_function_error() 也会被调用。很抱歉。

以上是关于调用render()时如何获取Django模板错误的文件名和行号?的主要内容,如果未能解决你的问题,请参考以下文章

8.Django怎样去调用漂亮的HTML前端页面?

Django 模板 render传参不转码

django - render_to_response - 渲染了一些东西

Django HttpResponse

Django学习系列之模板

在每个 Django 页面中传递一个对象