UnT*_*hie 4 django django-templates
我想为我的 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”。
有没有办法将请求对象传递给自定义模板加载器?
小智 5
我一直在寻找相同的解决方案,经过几天的搜索,我决定使用 threading.local()。只需在 HTTP 请求处理期间将请求对象设为全局即可!开始从画廊扔烂番茄。
让我解释:
从 Django 1.8(根据开发版本文档)开始,所有模板查找函数的“dirs”参数都将被弃用。(参考)
这意味着除了被请求的模板名称和模板目录列表之外,没有任何参数传递给自定义模板加载器。如果您想访问请求 URL 中的参数(甚至会话信息),您将不得不“接触”其他一些存储机制。
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
Run Code Online (Sandbox Code Playgroud)
在我的情况下,它不是我所追求的请求对象(直接),而是模板应该呈现给哪个站点(我正在开发 SaaS 解决方案)。
为了找到渲染模板,Django 使用get_template仅获取template_name和 可选dirs参数的方法。所以你不能真正在那里传递请求。
但是,如果您自定义render_to_response函数来传递dirs参数,您应该能够做到这一点。
例如(假设您RequestContext像大多数人一样使用 a ):
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)
Run Code Online (Sandbox Code Playgroud)