Python 如果缺少模板,则更好地显示错误消息

Python 如果缺少模板,则更好地显示错误消息,python,django,debugging,django-templates,Python,Django,Debugging,Django Templates,如果django模板的呈现中缺少模板,则会出现如下异常 经过很长时间的搜索,我发现了伪造的部分: {% include form.template_name %} form.template_名称在我的上下文中为空 如何在不搜索数小时的情况下找到相关模板名称 我缺少一个类似于普通python代码的回溯。“普通”python回溯向我显示包含bug的文件和行 /home/foo_fm_d/bin/python /usr/local/pycharm-community-4.5/helpers/py

如果django模板的呈现中缺少模板,则会出现如下异常

经过很长时间的搜索,我发现了伪造的部分:

 {% include form.template_name %}
form.template_名称在我的上下文中为空

如何在不搜索数小时的情况下找到相关模板名称

我缺少一个类似于普通python代码的回溯。“普通”python回溯向我显示包含bug的文件和行

/home/foo_fm_d/bin/python /usr/local/pycharm-community-4.5/helpers/pycharm/utrunner.py /home/foo_fm_d/src/foo-time/foo_time/tests/unit/views/user/test_preview_of_next_days.py::EditTestCase::test_preview_of_next_days true
Testing started at 09:26 ...

Error
Traceback (most recent call last):
  File "/home/foo_fm_d/src/foo-time/foo_time/tests/unit/views/user/test_preview_of_next_days.py", line 11, in test_preview_of_next_days
    self.admin_client.get(url)
  File "/home/foo_fm_d/src/djangotools/djangotools/utils/testutils.py", line 275, in get
    response = super(Client, self).get(path, data, **extra)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/test/client.py", line 473, in get
    response = super(Client, self).get(path, data=data, **extra)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/test/client.py", line 280, in get
    return self.request(**r)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/test/client.py", line 444, in request
    six.reraise(*exc_info)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 137, in get_response
    response = response.render()
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/response.py", line 105, in render
    self.content = self.rendered_content
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/response.py", line 82, in rendered_content
    content = template.render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/base.py", line 140, in render
    return self._render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/base.py", line 134, in _render
    return self.nodelist.render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/base.py", line 840, in render
    bit = self.render_node(node, context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/debug.py", line 78, in render_node
    return node.render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/loader_tags.py", line 123, in render
    return compiled_parent._render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/base.py", line 134, in _render
    return self.nodelist.render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/base.py", line 840, in render
    bit = self.render_node(node, context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/debug.py", line 78, in render_node
    return node.render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/loader_tags.py", line 123, in render
    return compiled_parent._render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/base.py", line 134, in _render
    return self.nodelist.render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/base.py", line 840, in render
    bit = self.render_node(node, context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/debug.py", line 78, in render_node
    return node.render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/base.py", line 840, in render
    bit = self.render_node(node, context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/debug.py", line 78, in render_node
    return node.render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/debug.py", line 88, in render
    output = self.filter_expression.resolve(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/base.py", line 585, in resolve
    obj = self.var.resolve(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/base.py", line 735, in resolve
    value = self._resolve_lookup(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/base.py", line 789, in _resolve_lookup
    current = current()
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/loader_tags.py", line 72, in super
    return mark_safe(self.render(self.context))
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/base.py", line 840, in render
    bit = self.render_node(node, context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/debug.py", line 78, in render_node
    return node.render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/base.py", line 840, in render
    bit = self.render_node(node, context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/debug.py", line 78, in render_node
    return node.render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/loader_tags.py", line 62, in render
    result = block.nodelist.render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/base.py", line 840, in render
    bit = self.render_node(node, context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/debug.py", line 78, in render_node
    return node.render(context)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/loader_tags.py", line 166, in render
    template = get_template(template_name)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/loader.py", line 138, in get_template
    template, origin = find_template(template_name)
  File "/home/foo_fm_d/local/lib/python2.7/site-packages/django/template/loader.py", line 131, in find_template
    raise TemplateDoesNotExist(name)
TemplateDoesNotExist


Process finished with exit code 0
更新

我的个人背景:到目前为止,我一直避免使用django模板,因为有时候异常会被默默忽略,这样的回溯会让调试过程感觉像穿着混凝土制成的沉重鞋子

我试图消除我的偏见。或者至少找到一种方法,从模板中获得更好的错误消息

更新II


我通过pyCharm内部的单元测试看到了回溯。我没有看到视图的结果。“webbrowser”客户端调用该视图。我将TEMPLATE_DEBUG=True设置为True,但结果是相同的。

由于您似乎在使用PyCharm,您可以使用调试器来查看模板的上下文(为此设置断点)

另外,您使用的是哪个版本的Django?在我的(python3.4上的1.8)中,loader.py文件中没有find_template()。它可能因为这个原因被删除了


顺便说一句,TemplateDoesNotExist似乎总是以模板的名称作为param调用,我想是因为Being能够在错误消息中显示它,但在您的情况下,它是空的。也许这是它难以调试的另一个原因?

您没有看到常见的Python stacktrace的原因恰恰是Django模板不是Python

它是一种特定的语言,本身由Python解释,Python基于模板构建一个抽象语法树,然后在呈现阶段对该树求值。此时,默认情况下无法访问与源(例如模板文件)关联的信息

Django中有一个选项可以显示与呈现模板时引发的异常相关的更多相关信息,它是Django 1.8之前的
template\u DEBUG

此选项随Django 1.8和多个模板引擎的引入而更改,因为调试信息特定于模板引擎的每个实现


编辑:另请参见

老实说,我一直使用其他海报建议的机制与实时服务器配合使用。但是,由于您正在寻找一个可能在Jenkins中工作的解决方案,并且您的堆栈显示您正在使用debug.py,因此我查看了那里的调试数据

我注意到模板引擎应该在异常的django_template_source属性中为模板的失败部分添加一段源代码


这是否存在于您的异常中并有帮助?如果是这样,您可以捕获异常并在UT失败之前将其打印出来。

您是否尝试过此方法:?@Wtower我通过pyCharm内部的单元测试看到了回溯。我没有看到视图的结果。“webbrowser”
客户端
调用该视图。我设置了TEMPLATE_DEBUG=True,但结果是一样的。不幸的是
TEMPLATE_DEBUG=True
依赖于
DEBUG=True
,当测试运行时,该变量会自动设置为
False
。您能否运行一个真正的服务器(
/manage.py runserver
),并尝试在您的设置中使用
TEMPLATE\u DEBUG=DEBUG=True
在浏览器中重新生成它?@Weier它与TEMPLATE\u DEBUG=DEBUG=True相同True@guettli:您是否尝试在浏览器中真正运行该页面(使用这些设置)?这可能是调试错误的方法。我喜欢Python,因为如果出现错误,您会得到回溯。但是使用django模板,我得到了如上所述的回溯。我可以使用调试器,但是在第一次运行时发出一条好的错误消息非常重要。如果错误发生在CI期间(我们使用jenkins),那么我也只能得到一个ascii回溯。我们使用Django 1.6(我们将很快升级)和Python 2.7。我还使用回溯作为查找错误的第一个选项,因为它更简单、更快速,可以在调试器不够清晰或提供的信息不足时保留调试器。模板有时是这样的。由于-1,我不再被授权发布答案。不是我。我几乎从不反对投票。我投了更高的票。我希望你能再次发布答案。谢谢你!我想我可以再回答一遍。谢谢你仔细阅读并理解我的情况。我开发web应用程序,但如果我编写后端代码,而不使用web浏览器,我会编写单元测试。django调试页面很棒,但对于失败的测试不可见。当我写这篇文章时,我有了下一个想法。也许我可以启动lynx或w3m并将django调试页面的html输出转储到ascii…是的-如果您可以为您的内容启动测试服务器,这将是另一种获得它的方法。另一个想法是:您可以查看get_traceback_data in,以获取可以从异常中提取的进一步数据。