2013-04-02 27 views
6

有沒有可能在調試模式下將模板生成寫入生成的視圖詳細信息?例如,它可能會產生這樣的輸出:Django模板標籤中的詳細模式

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探索一些較大的依賴關係就非常困難。或者,也許你知道一些更好的工具更容易導航(生成圖等)?當然,這些信息只能在調試模式下生成。在生產中它們應該消失。

+2

好問題!你可能會看到['django-debug-toolbar'](https://github.com/django-debug-toolbar/django-debug-toolbar)或['django-template-repl'](https:// github .com/codysoyland/django-template-repl)很有幫助。 –

+0

對我來說'django-template-repl'完全沒用,因爲我需要輸入整個文件樹,如果我知道哪個文件是壞的答案,我會在沒有它的情況下回答。我創建了這個問題,因爲現在我維護的代碼中使用魔法模板標籤,這些代碼使用魔術,取決於插入的模型(模板列表:'({app_label}/{model}/{template} .html「,」{template} .html「)'),並且輸出與使用其內容的獨特模板太相似。 'django-debug-toolbar'已經很近了,但還不夠,現在我正在使用它。 – zwierzak

+0

魔法是邪惡的。你有沒有想過用一個sed腳本在每個block/include之後添加html註釋,並且在每個endblock之前? – ornoone

回答

2

您可能可以使用middlware實現此目的。我在回顧模板和視圖的過程中遇到了類似的問題,因此我編寫了一箇中間件代碼段,在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