【发布时间】:2016-06-22 04:29:48
【问题描述】:
我正在开发我的网站的移动版本,因此考虑使用用户代理作为为移动和网络版本提供不同模板的标准。 我成功地从 nginx 读取了用户代理信息,并将其作为标头传递给 gunicorn 服务器。
然后我创建了一个中间件,它读取此标头并更改设置文件中的模板目录。这似乎最初有效,但后来我意识到发生了竞争条件,因为这种方法不是线程安全的。 (我应该事先想到)。
所以我开始考虑其他选择。一种解决方案是覆盖 django 的渲染方法以包含基于请求标头的“dirs”参数。但后来我发现“dirs”参数已被弃用。以下是参考链接https://docs.djangoproject.com/en/1.9/_modules/django/shortcuts/#render 所以即使这样也行不通。
另一种解决方案是为移动和网络设置不同的模板名称并相应地加载它们。但是我不想这样做,并且希望保持模板目录结构对于 Web 和移动设备完全相同。
必须有一种方法来覆盖模板目录。如果移动模板目录中缺少模板,这将给我一个回退到网络版本模板的优势。
任何关于如何实现这一点的建议都会有所帮助。
这就是我的模板的组织方式。
App1
templates
App1
index.html
catalog.html
App2
templates
App2
about.html
在项目目录(不是app文件夹的一部分)中,有一个移动模板文件夹,其结构如下
mobile-templates
App1
index.html
App2
about.html
谢谢 阿努拉格
【问题讨论】:
-
修改
request对象添加目录名怎么样?然后render可以通过将路径附加到这个request.template_dir变量来呈现文件。 -
@SudhanshuShekhar - 即使我修改了请求对象,渲染函数如何自动获取目录名称?我也检查了源代码,并没有发现 request.template_dir 被渲染函数使用。不知道我是否遗漏了什么,请澄清。如果您的意思是在我的渲染函数中预先附加目录名称,那么回退到网络版本将不起作用。
-
我在想类似的东西:
render(request, ["app/template/t_mobile.html", "app/template/t.html"], context)。您可以使用request.template_dir来决定是否添加t_mobile.html作为选项。 -
我已经尝试过了,但是直到我在设置文件中定义了移动模板目录之后它才起作用。一旦我这样做了,我在渲染函数中指定的模板顺序就不再重要了。
标签: django django-templates thread-safety mobile-website django-middleware