我想为我的Django应用程序编写自定义模板加载器,该应用程序根据作为请求一部分的密钥查找特定文件夹。
让我进一步了解更多细节。假设我将在每个请求上获取一个密钥(我使用中间件填充)。
示例:request.key可以是'india'或'usa'或'uk'。
我希望我的模板加载器能够查找模板“templates/<key>/<template.html>
”。所以当我说{% include "home.html" %}
时,我希望模板加载器根据请求加载“templates / india / home.html”或“templates / usa / home.html”或“templates / uk / home.html” 。
有没有办法将请求对象传递给自定义模板加载器?
答案 0 :(得分:4)
我一直在寻找相同的解决方案,经过几天的搜索,决定使用threading.local()。只需在HTTP请求处理期间使请求对象全局化! 开始从画廊扔掉腐烂的番茄。
让我解释一下:
从Django 1.8开始(根据开发版本文档)&#34; dirs&#34;将弃用所有模板查找函数的参数。 (ref)
这意味着除了请求的模板名称和模板目录列表之外,没有传递给自定义模板加载器的参数。如果您想访问请求网址中的参数(甚至是会话信息),您必须&#34;伸出&#34;进入其他一些存储机制。
import threading
_local = threading.local()
class CustomMiddleware:
def process_request(self, request):
_local.request = request
def load_template_source(template_name, template_dirs=None):
if _local.request:
# Get the request URL and work your magic here!
pass
在我的情况下,它不是我直接访问的请求对象,而是应该呈现模板的网站(我正在开发SaaS解决方案)。
答案 1 :(得分:2)
要查找要渲染的模板,Django使用get_template
方法,该方法只获取template_name
和可选dirs
参数。所以你无法在那里真正传递请求。
但是,如果您自定义render_to_response
函数以传递dirs
参数,则应该能够执行此操作。
例如(假设你像大多数人一样使用RequestContext
):
from django import shortcuts
from django.conf import settings
def render_to_response(template_name, dictionary=None, context_instance=None, content_type=None, dirs):
assert context_instance, 'This method requires a `RequestContext` instance to function'
if not dirs:
dirs = []
dirs.append(os.path.join(settings.BASE_TEMPLATE_DIR, context_instance['request'].key)
return shortcuts.render_to_response(template_name, dictionary, context_instance, content_type, dirs)