有沒有一種更低級別的方式來提供模板時的加載器列表,而不是總是讓Django使用該設置?Django - 在每個請求的基礎上使用自定義模板加載器?
我想使用自定義模板加載器實例只有幾個意見(我有我的理由)。
有沒有一種更低級別的方式來提供模板時的加載器列表,而不是總是讓Django使用該設置?Django - 在每個請求的基礎上使用自定義模板加載器?
我想使用自定義模板加載器實例只有幾個意見(我有我的理由)。
它看起來像你必須寫一些自己的代碼來做到這一點。讓我們來看看裝載模板正常代碼路徑,如果你使用,也就是說,render_to_response
,其中the source相關部分是:
return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
這是對django.template.loader.render_to_string
一個電話,其通過一些其他的功能,並最終最終打電話給find_template
。
第一次調用find_template
時,根據settings.TEMPLATE_LOADERS
初始化全局template_source_loaders
緩存。所以看起來好像沒有什麼額外的參數可以傳入或者類似的東西。
一種可能性是僅在該視圖期間向django.template.loader.template_source_loaders
添加一些裝載機。我不知道這是否會導致其他問題;它感覺很髒,但如果它有效,它會很容易。 (只要製作一個視圖裝飾器就行)
如果你不想這樣做,它看起來像你必須用你自己的代碼複製render_to_string
的工作(如果你真的確定你想要使用每個視圖模板加載器,爲了解決這個問題,我接受這個模板加載器作爲前提,但我敢打賭實際上並不需要)。這裏沒有太多的代碼,如果事先知道要使用的特定加載器和單個模板名稱,那實際上很簡單。 (這是未經測試,但可能會相當多的工作。)
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。
我最終這樣做是通過修改template_source_loaders爲Dougal建議的。就像他說的那樣,我不確定這是否安全(它能否創造競爭條件?),但此時它適用於我的特殊情況。 Dougal建議以這種方式進行這種方式的好處是,它確保{%extends%}和{%include%}也使用修改後的加載程序。這是我的render_to_string自定義裝載機:
def render_to_string_with_loader(*args, **kwargs):
""" Call render_to_string using ReportTemplateLoader to find templates. """
import django.template.loader as loader
old_loaders = settings.TEMPLATE_LOADERS
settings.TEMPLATE_LOADERS = ('main.loaders.ReportTemplateLoader',)
loader.template_source_loaders = None # force refresh from settings
try:
out = render_to_string(*args, **kwargs)
finally:
# use finally make sure template errors can't mess up later requests
settings.TEMPLATE_LOADERS = old_loaders
loader.template_source_loaders = None
甜,感謝Dougal。 – orokusaki