django-debug-toolbar: 'Template' object has no attribute 'engine'

倾然丶 夕夏残阳落幕 提交于 2019-12-06 12:28:43

问题


I've just tried running an existing Django project on a new computer, and I'm having trouble with django-debug-toolbar. It seems to be something to do with Jinja2. Here's the stack trace:

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'

I'm using django-jinja2 to integrate Jinja2 into my project, and this worked okay before but it now seems to be expecting this template variable to be a normal Django template. In my TEMPLATES setting I have both Jinja2 and DjangoTemplates set up, with Jinja2 using a specific extension ('tmpl') to make sure only those templates are used by Jinja2 and everything else can go through the DjangoTemplates backend.

Has anyone seen this error before when using django debug toolbar with Jinja2? I can post more settings if needed.

EDIT: As requested, here's my TEMPLATES settings:

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",
            ]
        }
    }
]

Update - I've "fixed" the issue by making a small code change in the debug toolbar source: changing line 175 in debug_toolbar/panels/templates/panel.py from:

template_dirs = self.templates[0]['template'].engine.dirs

to:

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']))

I haven't looked into why this works (for some people this combination of debug toolbar 1.5 and django-jinja 2.2.0 works fine) but I noticed that Jinja2 templates have the backend attribute and the Django templates have the engine attribute, and both appear to be used for the same thing.


回答1:


I get this too, you can hack it fixed based on your suggestion without hacking core by supplying your own panel 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',
]



回答2:


self.template may be empty, I think this is due to the cached ... In any case, need to replace:

template = self.templates[0]['template']

to

template = None
try:
    template = self.templates[0]['template']
except IndexError:
    pass


来源:https://stackoverflow.com/questions/38569760/django-debug-toolbar-template-object-has-no-attribute-engine

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!