django-debug-toolbar: 'Template' 对象没有属性 'engine'
django-debug-toolbar: 'Template' object has no attribute 'engine'
我刚刚在一台新计算机上 运行 尝试了一个现有的 Django 项目,但我在使用 django-debug-toolbar 时遇到了问题。好像跟Jinja2有关。这是堆栈跟踪:
Traceback:
File "/path/to/myrepo/env/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
223. response = middleware_method(request, response)
File "/path/to/myrepo/env/local/lib/python2.7/site-packages/debug_toolbar/middleware.py" in process_response
120. panel.generate_stats(request, response)
File "/path/to/myrepo/env/local/lib/python2.7/site-packages/debug_toolbar/panels/templates/panel.py" in generate_stats
175. context_processors = self.templates[0]['context_processors']
Exception Type: AttributeError at /first/page/
Exception Value: 'Template' object has no attribute 'engine'
我正在使用 django-jinja2 将 Jinja2 集成到我的项目中,这之前工作正常,但现在似乎希望这个 template
变量成为一个普通的 Django 模板。在我的 TEMPLATES
设置中,我同时设置了 Jinja2 和 DjangoTemplates,Jinja2 使用特定的扩展名 ('tmpl') 以确保只有那些模板被 Jinja2 使用,其他一切都可以通过 DjangoTemplates 后端。
有人在使用 Django 调试工具栏和 Jinja2 时遇到过这个错误吗?如果需要,我可以 post 更多设置。
编辑:根据要求,这是我的模板设置:
TEMPLATES = [
{
#'BACKEND': 'django.template.backends.jinja2.Jinja2',
'BACKEND': 'django_jinja.backend.Jinja2',
#'NAME': 'jinja2',
'DIRS': [
os.path.join(DEPLOY_PATH, 'templates')
],
'APP_DIRS': True,
'OPTIONS': {
'debug': DEBUG,
'match_extension': '.tmpl',
#'environment': 'jinja2.Environment',
'extensions': [
'jinja2.ext.with_',
'jinja2.ext.i18n',
'django_jinja.builtins.extensions.UrlsExtension',
'django_jinja.builtins.extensions.CsrfExtension',
'pipeline.templatetags.ext.PipelineExtension',
],
'context_processors': [
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.static",
"django.contrib.messages.context_processors.messages",
"django.core.context_processors.request",
]
},
},
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(DEPLOY_PATH, 'templates')
],
'APP_DIRS': True,
'OPTIONS': {
'debug': DEBUG,
'context_processors': [
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.static",
"django.contrib.messages.context_processors.messages",
"django.core.context_processors.request",
]
}
}
]
更新 - 我通过在调试工具栏源代码中进行小的代码更改来解决 "fixed" 问题:将 debug_toolbar/panels/templates/panel.py
中的第 175 行更改为:
template_dirs = self.templates[0]['template'].engine.dirs
至:
if hasattr(self.templates[0]['template'], 'engine'):
template_dirs = self.templates[0]['template'].engine.dirs
elif hasattr(self.templates[0]['template'], 'backend'):
template_dirs = self.templates[0]['template'].backend.dirs
else:
raise RuntimeError("Couldn't find engine or backend for a template: {}",format(self.templates[0]['template']))
我还没有研究为什么这有效(对于某些人来说,调试工具栏 1.5 和 django-jinja 2.2.0 的这种组合工作正常)但我注意到 Jinja2 模板具有 backend
属性和Django 模板具有 engine
属性,两者似乎用于同一件事。
我也明白了,你可以根据你的建议破解它,而无需通过提供你自己的面板来破解核心 class:
debug.py
from debug_toolbar.panels.templates import TemplatesPanel as BaseTemplatesPanel
class TemplatesPanel(BaseTemplatesPanel):
def generate_stats(self, *args):
template = self.templates[0]['template']
if not hasattr(template, 'engine') and hasattr(template, 'backend'):
template.engine = template.backend
return super().generate_stats(*args)
settings.py
DEBUG_TOOLBAR_PANELS = [
'debug_toolbar.panels.versions.VersionsPanel',
'debug_toolbar.panels.timer.TimerPanel',
'debug_toolbar.panels.settings.SettingsPanel',
'debug_toolbar.panels.headers.HeadersPanel',
'debug_toolbar.panels.request.RequestPanel',
'debug_toolbar.panels.sql.SQLPanel',
'debug_toolbar.panels.staticfiles.StaticFilesPanel',
'myapp.debug.TemplatesPanel', # original broken by django-jinja, remove this whole block later
'debug_toolbar.panels.cache.CachePanel',
'debug_toolbar.panels.signals.SignalsPanel',
'debug_toolbar.panels.logging.LoggingPanel',
'debug_toolbar.panels.redirects.RedirectsPanel',
]
self.template
可能是空的,我想这是缓存的原因。。。不管怎样,
需要更换:
template = self.templates[0]['template']
到
template = None
try:
template = self.templates[0]['template']
except IndexError:
pass
我刚刚在一台新计算机上 运行 尝试了一个现有的 Django 项目,但我在使用 django-debug-toolbar 时遇到了问题。好像跟Jinja2有关。这是堆栈跟踪:
Traceback:
File "/path/to/myrepo/env/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
223. response = middleware_method(request, response)
File "/path/to/myrepo/env/local/lib/python2.7/site-packages/debug_toolbar/middleware.py" in process_response
120. panel.generate_stats(request, response)
File "/path/to/myrepo/env/local/lib/python2.7/site-packages/debug_toolbar/panels/templates/panel.py" in generate_stats
175. context_processors = self.templates[0]['context_processors']
Exception Type: AttributeError at /first/page/
Exception Value: 'Template' object has no attribute 'engine'
我正在使用 django-jinja2 将 Jinja2 集成到我的项目中,这之前工作正常,但现在似乎希望这个 template
变量成为一个普通的 Django 模板。在我的 TEMPLATES
设置中,我同时设置了 Jinja2 和 DjangoTemplates,Jinja2 使用特定的扩展名 ('tmpl') 以确保只有那些模板被 Jinja2 使用,其他一切都可以通过 DjangoTemplates 后端。
有人在使用 Django 调试工具栏和 Jinja2 时遇到过这个错误吗?如果需要,我可以 post 更多设置。
编辑:根据要求,这是我的模板设置:
TEMPLATES = [
{
#'BACKEND': 'django.template.backends.jinja2.Jinja2',
'BACKEND': 'django_jinja.backend.Jinja2',
#'NAME': 'jinja2',
'DIRS': [
os.path.join(DEPLOY_PATH, 'templates')
],
'APP_DIRS': True,
'OPTIONS': {
'debug': DEBUG,
'match_extension': '.tmpl',
#'environment': 'jinja2.Environment',
'extensions': [
'jinja2.ext.with_',
'jinja2.ext.i18n',
'django_jinja.builtins.extensions.UrlsExtension',
'django_jinja.builtins.extensions.CsrfExtension',
'pipeline.templatetags.ext.PipelineExtension',
],
'context_processors': [
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.static",
"django.contrib.messages.context_processors.messages",
"django.core.context_processors.request",
]
},
},
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(DEPLOY_PATH, 'templates')
],
'APP_DIRS': True,
'OPTIONS': {
'debug': DEBUG,
'context_processors': [
"django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.static",
"django.contrib.messages.context_processors.messages",
"django.core.context_processors.request",
]
}
}
]
更新 - 我通过在调试工具栏源代码中进行小的代码更改来解决 "fixed" 问题:将 debug_toolbar/panels/templates/panel.py
中的第 175 行更改为:
template_dirs = self.templates[0]['template'].engine.dirs
至:
if hasattr(self.templates[0]['template'], 'engine'):
template_dirs = self.templates[0]['template'].engine.dirs
elif hasattr(self.templates[0]['template'], 'backend'):
template_dirs = self.templates[0]['template'].backend.dirs
else:
raise RuntimeError("Couldn't find engine or backend for a template: {}",format(self.templates[0]['template']))
我还没有研究为什么这有效(对于某些人来说,调试工具栏 1.5 和 django-jinja 2.2.0 的这种组合工作正常)但我注意到 Jinja2 模板具有 backend
属性和Django 模板具有 engine
属性,两者似乎用于同一件事。
我也明白了,你可以根据你的建议破解它,而无需通过提供你自己的面板来破解核心 class:
debug.py
from debug_toolbar.panels.templates import TemplatesPanel as BaseTemplatesPanel
class TemplatesPanel(BaseTemplatesPanel):
def generate_stats(self, *args):
template = self.templates[0]['template']
if not hasattr(template, 'engine') and hasattr(template, 'backend'):
template.engine = template.backend
return super().generate_stats(*args)
settings.py
DEBUG_TOOLBAR_PANELS = [
'debug_toolbar.panels.versions.VersionsPanel',
'debug_toolbar.panels.timer.TimerPanel',
'debug_toolbar.panels.settings.SettingsPanel',
'debug_toolbar.panels.headers.HeadersPanel',
'debug_toolbar.panels.request.RequestPanel',
'debug_toolbar.panels.sql.SQLPanel',
'debug_toolbar.panels.staticfiles.StaticFilesPanel',
'myapp.debug.TemplatesPanel', # original broken by django-jinja, remove this whole block later
'debug_toolbar.panels.cache.CachePanel',
'debug_toolbar.panels.signals.SignalsPanel',
'debug_toolbar.panels.logging.LoggingPanel',
'debug_toolbar.panels.redirects.RedirectsPanel',
]
self.template
可能是空的,我想这是缓存的原因。。。不管怎样,
需要更换:
template = self.templates[0]['template']
到
template = None
try:
template = self.templates[0]['template']
except IndexError:
pass