Лучшее сообщение об ошибках, если шаблон отсутствует
Если шаблон отсутствует внутри рендеринга шаблона django, я получаю исключение, как показано ниже.
После долгого поиска я нашел фиктивную часть:
{% include form.template_name %}
form.template_name в моем контексте было пустым.
Как найти подходящее имя шаблона без поиска часов?
Мне не хватает трассировки, как для обычного кода на Python. "Нормальные" трассировки python показывают мне файл и строку, содержащие ошибку.
/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
Я вижу трассировку через unittest внутри pyCharm. Я не читаю результат обзора. Клиент "webbrowser" вызывает представление. Я установил TEMPLATE_DEBUG = True, но результат тот же.
Ответы
Ответ 1
Честно говоря, я всегда использовал механизмы, предлагаемые другими плакатами с живым сервером. Однако, поскольку вы ищете решение, которое может работать в Jenkins, и ваш стек показывает, что вы проходите через debug.py, я просмотрел там отладочные данные.
Я заметил, что движок шаблона должен добавить фрагмент исходного кода для поврежденной части шаблона в атрибуте django_template_source в Exception.
Является ли это в вашем исключении и полезным? Если это так, вы можете поймать исключение и распечатать его перед сбоем UT.
Ответ 2
Причина, по которой вы не видите обычную стеклу Python, это именно то, что шаблоны Django не являются Python.
Это конкретный язык, который сам интерпретируется Python, который строит абстрактное синтаксическое дерево на основе шаблона и затем оценивает это дерево во время фазы рендеринга. На данный момент информация, связанная с источником (например, файл шаблона), по умолчанию недоступна.
В Django есть опция для отображения более релевантной информации, связанной с исключением, созданным при рендеринге шаблона, TEMPLATE_DEBUG
перед DJango 1.8.
См. https://docs.djangoproject.com/en/1.8/ref/settings/#template-debug
Эта опция была изменена с помощью Django 1.8 и внедрением нескольких механизмов шаблонов, поскольку информация об отладке относится к каждой реализации механизма шаблонов.
Изменить: см. также Что такое параметр TEMPLATE_DEBUG для Django для?
Ответ 3
Как вы, кажется, используете PyCharm, вы можете использовать отладчик, который позволяет вам просматривать контекст ваших шаблонов (разместить точки останова для этого) documentation
Также, какую версию Django вы используете? В моем (1.8 на python3.4) в файле loader.py нет find_template(). Возможно, это было удалено по этой причине?
Btw, TemplateDoesNotExist, кажется, всегда вызывается с именем шаблона в качестве параметра, я думаю, что он не смог отобразить его в сообщении об ошибке, но в вашем случае он пуст. Может быть, это еще одна причина для его отладки?