如何让Django在遇到时告诉我,例如,在呈现模板时出现未定义的变量错误?
我尝试了显而易见的DEBUG = True
和TEMPLATE_DEBUG = True
,但他们没有帮助。
答案 0 :(得分:26)
将其放入调试设置中:
class InvalidString(str):
def __mod__(self, other):
from django.template.base import TemplateSyntaxError
raise TemplateSyntaxError(
"Undefined variable or unknown value for: \"%s\"" % other)
TEMPLATE_STRING_IF_INVALID = InvalidString("%s")
当模板引擎看到或发现未定义的值时,这会引发错误。
答案 1 :(得分:10)
根据django文档, 默认情况下,未定义的变量被视为''(空字符串)。在 if for regroup 时,它是 None 。 如果要识别变量undefined,请在设置中更改TEMPLATE_STRING_IF_INVALID。 '%s'使无效变量呈现为其变量名,这样,您就可以轻松识别。 how-invalid-variables-are-handled
答案 2 :(得分:4)
似乎Django依赖于未定义的变量是一个简单的空字符串。因此,不要改变这种行为或使其抛出异常,而是让它保持相同,但让它记录警告!
在settings.py
文件中:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# ...
'OPTIONS': {
# ...
'string_if_invalid': InvalidStringShowWarning("%s"),
},
}
]
(string_if_invalid
替换了较新的Django版本中的TEMPLATE_STRING_IF_INVALID
。)
更进一步说,你需要定义InvalidStringShowWarning
类,使其在记录警告时表现出来:
class InvalidStringShowWarning(str):
def __mod__(self, other):
import logging
logger = logging.getLogger(__name__)
logger.warning("Undefined variable or unknown value for: '%s'" % (other,))
return ""
您应该能够在python manage.py runserver
的输出中看到警告。
答案 3 :(得分:2)
在模板中阅读how invalid variable are handled。基本上,只需将TEMPLATE_STRING_IF_INVALID设置为settings.py中的内容即可。
TEMPLATE_STRING_IF_INVALID = "He's dead Jim! [%s]"
答案 4 :(得分:2)
我认为这是对Django的主要疏忽,也是我不想使用默认模板引擎的主要原因。可悲的事实是,至少现在(Django 1.9),你无法可靠地实现这种效果。
你可以让Django在遇到{{ undefined_variable }}
时引发异常 - 使用slacy的答案中描述的“hack”。
你无法让Django在{% if undefined_variable %}
或{% for x in undefined_variable %}
等处引发相同的异常。“hack”在这种情况下不起作用。< / p>
即使在你可以的情况下,Django作者强烈反对在生产环境中使用这种技术。除非您确定不在应用中使用Django的内置模板,否则您应该在DEBUG
模式下使用“hack” 。
但是,如果您暂时停留在Django的模板中,我建议您使用slacy的答案,只需确保您处于DEBUG
模式。
答案 5 :(得分:2)
查找上下文中不存在的模板变量对我来说非常重要,因为有几次错误使其生成,因为视图已更改但模板没有。
我在manage.py
中使用了这种技术,以便在使用上下文中找不到模板变量时实现破解测试的效果。请注意,此技术适用于for
循环和if
语句,而不仅仅是{{ variables }}
。
import sys
# sometimes it's OK if a variable is undefined:
allowed_undefined_variables = [
'variable_1',
'variable_2',
]
if 'test' in sys.argv:
import django.template.base as template_base
old_resolve = template_base.Variable.resolve
def new_resolve(self, context):
try:
value = old_resolve(self, context)
except template_base.VariableDoesNotExist as e:
# if it's not a variable that's allowed to not exist then raise a
# base Exception so Nodes can't catch it (which will make the test
# fail)
if self.var not in allowed_undefined_variables:
raise Exception(e)
# re-raise the original and let the individual Nodes deal with it
# however they'd like
raise e
return value
template_base.Variable.resolve = new_resolve
答案 6 :(得分:0)
我下次使用
import logging
from django.utils.html import format_html
from django.utils.safestring import mark_safe
class InvalidTemplateVariable(str):
"""
Class for override output that the Django template system
determinated as invalid (e.g. misspelled) variables.
"""
# styles for display message in HTML`s pages
styles = mark_safe('style="color: red; font-weight: bold;"')
def __mod__(self, variable):
"""Overide a standart output here."""
# access to current settings
from django.conf import settings
# display the message on page in make log it only on stage development
if settings.DEBUG is True:
# format message with captured variable
msg = 'Attention! A variable "{}" does not exists.'.format(variable)
# get logger and make
logger = self.get_logger()
logger.warning(msg)
# mark text as non-escaped in HTML
return format_html('<i {}>{}</i>', self.styles, msg)
# on production it will be not displayed
return ''
def get_logger(self):
"""Create own logger with advanced error`s details."""
logger = logging.getLogger(self.__class__.__name__)
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
在设置文件中使用(默认情况下为settings.py):
TEMPLATES = [
{
......
'OPTIONS': {
.....................
'string_if_invalid': InvalidTemplateVariable('%s'),
.....................
},
},
]
或直接
TEMPLATES[0]['OPTIONS']['string_if_invalid'] = InvalidTemplateVariable('%s')
如果DEBUG = True:
的结果在页面上
在控制台中
> System check identified 1 issue (0 silenced). October 03, 2016 -
> 12:21:40 Django version 1.10.1, using settings 'settings.development'
> Starting development server at http://127.0.0.1:8000/ Quit the server
> with CONTROL-C. 2016-10-03 12:21:44,472 - InvalidTemplateVariable -
> WARNING - Attention! A variable "form.media" does not exists.
答案 7 :(得分:0)
您可以使用 pytest-django setting FAIL_INVALID_TEMPLATE_VARS
如果 pytest 执行代码,则检查无效变量。
[pytest]
DJANGO_SETTINGS_MODULE = mysite.settings
FAIL_INVALID_TEMPLATE_VARS = True
答案 8 :(得分:-3)
如果模板中有未定义的变量,django将不会告诉你。
您可以在视图中打印此变量。