Django - 根据每个请求使用自定义模板加载器? [英] Django - use custom template loader on a per-request basis?
问题描述
在渲染模板时,是否提供加载器列表的较低级别,而不是始终使用Django设置?
Is there a lower-level way to provide the list of loaders when rendering a template, as opposed to always having Django use the setting?
我想使用自定义模板加载器实例只有几个视图(我有我的理由)。
I'd like to use a custom template loader instance for only a few views (I have my reasons).
推荐答案
看起来你会必须写一些你自己的代码来做。我们来看看加载模板的正常代码路径,如果您使用 render_to_response
,那么源是:
It looks like you'll have to write some code of your own to do it. Let's take a look at the normal code path for loading templates, if you use, say, render_to_response
, where the relevant part of the source is:
return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
这是致电 django.template.loader.render_to_string
,它通过一些其他功能,最终最终调用 find_template
。
That's a call to django.template.loader.render_to_string
, which passes through some other functions and eventually ends up calling find_template
.
首次调用 find_template
时,根据 template_source_loaders
> settings.TEMPLATE_LOADERS 。所以看起来你没有什么可以传入的任何额外的参数,或者像这样的任何东西。
The first time find_template
is called, in initializes the global template_source_loaders
cache based on settings.TEMPLATE_LOADERS
. So it looks like there's no just extra argument you can pass in or anything like that.
有一种可能是将一些加载器添加到 django。 template.loader.template_source_loaders
仅在该视图的持续时间内。我不知道是否会造成其他问题;它感觉很脏,但如果它的工作,这将是很容易的。 (只是做一个视图装饰器)。
One possibility might be to add some loaders to django.template.loader.template_source_loaders
just for the duration of that view. I don't know if that will cause other problems; it feels dirty, but if it works, it'll be pretty easy. (Just make a view decorator that does it.)
如果你不想这样做,你将不得不复制 render_to_string
与你自己的代码(如果你真的确定要使用每个视图模板加载程序,我接受作为前提为了这个问题,但我敢打赌实际上不是必需的)没有那么多的代码,如果你提前知道一个特定的加载程序和一个你想要使用的模板名称,这其实很简单。 (这是未经测试的,但可能几乎可以工作。)
If you don't want to do that, it looks like you'll have to replicate the work of render_to_string
with your own code (if you're really sure you want to use per-view template loaders, which I'm accepting as a premise for the sake of this question but I bet isn't actually necessary). There's not all that much code there, and if you know in advance a specific loader and a single template name that you want to use, it's actually pretty easy. (This is untested but will probably pretty much work.)
def render_to_response_with_loader(loader, name,
dictionary=None, context_instance=None, mimetype=None, dirs=None):
# from find_template
t, display_name = loader(name, dirs)
# from get_template
if not hasattr(t, 'render'):
# template needs to be compiled
t = django.template.loader.get_template_from_string(t, origin, template_name)
# from render_to_string
if not context_instance:
rendered = t.render(Context(dictionary))
else:
# Add the dictionary to the context stack, ensuring it gets removed again
# to keep the context_instance in the same state it started in.
context_instance.update(dictionary)
try:
rendered = t.render(context_instance)
finally:
context_instance.pop()
# from render_to_response
return HttpResponse(rendered, mimetype=mimetype)
如果要支持多个可能的装载程序或可能的文件名列表,只需从 django.template.loader 。
If you want to support multiple possible loaders or a list of possible filenames, just copy the relevant code from django.template.loader.
这篇关于Django - 根据每个请求使用自定义模板加载器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!