【问题标题】:Verbose mode in Django template tagsDjango 模板标签中的详细模式
【发布时间】:2013-04-02 20:52:53
【问题描述】:

是否有可能在调试模式下将有关模板生成的详细信息写入生成的视图?例如它可以生成这样的输出:

base.html:

<html>
<body>
{% block content %}
{% endblock %}
</body>
</html>

page.html:

{% extend "base.html" %}
{% block content %}
Foo
{% include "inner.html" %}
Bar
{% endblock %}

变成这样的形式:

<html>
<body>
<!-- block content -->
<!-- from "page.html" -->
Foo
<!-- include "inner.html" -->
Bar
<!-- endblock content -->
</body>
</html>

为什么?因为有时仅通过 IDE 就很难探索一些更大的依赖项。或者,也许您知道一些便于导航(生成图表等)的好工具?当然,这些信息只能在调试模式下生成。在生产中它们应该会消失。

【问题讨论】:

  • 好问题!您可能会看看django-debug-toolbardjango-template-repl 是否有帮助。
  • 对我来说django-template-repl 完全没用,因为我需要将整个文件树输入其中,如果我知道哪个文件不好的答案,我会在没有它的情况下得到答案。我创建了这个问题是因为我现在维护的代码中的魔术模板标签,它们根据插入的模型使用魔术(模板作为列表:("{app_label}/{model}/{template}.html", "{template}.html")),并且输出与使用其内容的不同模板过于相似。 django-debug-toolbar 很接近,但还不够,现在我正在使用它。
  • 魔法是邪恶的。你有没有想过一个小 sed 脚本在每个块/包含之后和每个 endblock 之前添加 html 注释?
  • 假设这严格用于开发/调试目的,您可以在解析或预解析阶段对 Django 模板系统进行monkeypatch/instrument 以在每个{% block ... %}/{% endblock %} 附近添加一个HTML 注释。 ..

标签: python django django-templates


【解决方案1】:

您也许可以使用中间件来实现这一点。我在跟踪模板和调用它们的视图时遇到了类似的问题,所以我编写了一个中间件 sn-p,在 html 响应的顶部添加了一个注释块。它并不能完全满足您的要求,但您可能能够适应它。

COMMENT_BLOCK = """
<!--
[ url      ] >> http://%(host)s%(path)s
[ referer  ] >> %(referer)s
[ module   ] >> %(module)s
[ function ] >> %(function)s, line %(line)s
[ args     ] >> args=%(args)s, kwargs=%(kwargs)s, defaults=%(defaults)s
[ template ] >> %(template)s
-->

"""

# Add any additional template types you wish to add the comment block to.
MIMETYPES = (
    "text/html",
    "text/xml",
)


class HtmlTemplateFinder:

    def __init__(self):
        self.host = None
        self.referer = None
        self.path = None
        self.module = None
        self.function = None
        self.line = None
        self.args = None
        self.kwargs = None
        self.defaults = None
        self.template = None
        self.valid_template = False

    def _populate_comment_block(self):
        return COMMENT_BLOCK % {
                                'host': self.host,
                                'referer': self.referer,
                                'path': self.path,
                                'module': self.module,
                                'function': self.function,
                                'line': self.line,
                                'args': self.args,
                                'kwargs': self.kwargs,
                                'defaults': self.defaults,
                                'template': self.template,
                               }

    def process_view(self, request, view_func, view_args, view_kwargs):
        self.host = request.META.get('HTTP_HOST', None)
        self.referer = request.META.get('HTTP_REFERER', None)
        self.path = request.path
        self.module = view_func.func_code.co_filename
        self.function = ('.').join((view_func.__module__, view_func.func_name))
        self.line = view_func.func_code.co_firstlineno
        self.args = view_args
        self.kwargs = view_kwargs
        self.defaults = view_func.func_defaults
        return None

    def process_template_response(self, request, response):
        from mimetypes import guess_type
        # Use this rather than response.template_name, this always returns str
        self.template = response.resolve_template(response.template_name).name
        self.valid_template = guess_type(self.template)[0] in MIMETYPES
        return response

    def process_response(self, request, response):
        from <your app> import settings
        if settings.DEBUG:
            if self.valid_template:
                block = self._populate_comment_block()
                response.content = "%s%s" % (block, response.content)
        return response

【讨论】:

    猜你喜欢
    • 2011-12-09
    • 1970-01-01
    • 1970-01-01
    • 2017-03-27
    • 1970-01-01
    • 2010-11-09
    相关资源
    最近更新 更多