我正在尝试调整我为家庭项目编写的一块中间件。中间件的目标是在HTML或XML(或其他用户定义的模板类型)的顶部附加注释块,以显示有关该模板的信息,例如调用它的视图,模板位置等。它对于调试非常有用,特别是在处理您不熟悉的项目时,因为它允许您快速识别模板及其位置。
问题是,为了获取模板名称,它依赖于在视图中使用SimpleTemplateResponse,因为它包含模板名称,因此可以在process_template_response()中的中间件中获取它。
这显然使得中间件移植到现有项目中是非常不切实际的,因为通常使用render_to_response(),并返回一个HttpResponse对象,该对象更长时间知道用于渲染它的模板。
我编写的模板标识符的第一个实例(我从中调整了我的版本)的人,我曾经在一个项目中使用过,使用了threading.currentThread()或类似的东西,并找到了这样的模板名称并将其传递给中间件,但我无法访问该代码,因此无法检查它是如何完成的。
有没有人知道访问不涉及使用SimpleTemplateResponse的模板名称的方法,或者理想地修补render_to_response(虽然我会接受它,如果它似乎是唯一的方法)?
中间件:
# Base template for the html/url locator comment block
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:
"""
Middleware class that adds a comment block to an html response object.
Currently adds url, referer, the python module and its function/line,
the function arguments, and the template passed in. Only triggers if
a SimpleTemplateResponse object was used to render the template and
the template is .html.
"""
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):
import threading
print threading.current_thread.request
if settings.DEBUG:
if self.valid_template:
block = self._populate_comment_block()
response.content = "%s%s" % (block, response.content)
return response
答案 0 :(得分:2)
您可能希望使用django-debug-toolbar和template面板,而不是重新发明轮子。
仅供参考,正如您所看到的,它通过猴子修补django Template
类来获取模板名称。该代码基于this snippet。
希望有所帮助。