在 Django 的 TEMPLATE_DIRS 中使用外部 URL

发布于 2024-12-16 22:38:35 字数 946 浏览 2 评论 0原文

Settings.py 中的 Django TEMPLATE_DIRS 调用 unix 样式斜杠。

因此,当我调用

get_template('some/template.html')

视图时,结果总是从根开始,并导致调用

/home/username/projectname/public/some/template.html

问题是我想使用托管在完全不同的站点上的模板。这对于其他 Settings.py 字段(MEDIA_URL 和 STATIC_URL)效果很好,它会毫无异议地采用绝对 http 路径。

给定一个http路径,

 TEMPLATE_DIRS ('http://example.com/',)

在Settings.py中将强制

get_template('some/template.html')

在一个视图中尝试并找到

/home/username/projectname/public/http://example.com/some/template.html

我已经尝试像这样绕过它

TEMPLATE_DIRS ('../../../../http://example.com/',)

但它仍然强制一个前导斜杠,所以我得到“/http://example.com”,其中是没用的。

我的问题:

  1. 有没有办法欺骗它来提取模板文件 另一个服务器?
  2. 鉴于模板文件需要 为视图进行处理?
  3. 是否可以创建一个不需要unix风格斜杠的“django.template.loaders.filesystem.Loader”替代方案?

Django's TEMPLATE_DIRS in Settings.py calls for unix style slashes.

Because of this, when I call

get_template('some/template.html')

in a view, the result always starts at the root, and results in a call to

/home/username/projectname/public/some/template.html

The problem is that I'd like to use templates hosted on an entirely different site. This works fine for other Settings.py fields (MEDIA_URL and STATIC_URL), where it will take an absolute http path with no objection.

Given an http path,

 TEMPLATE_DIRS ('http://example.com/',)

in Settings.py will force

get_template('some/template.html')

in a view to try and find

/home/username/projectname/public/http://example.com/some/template.html

I've tried to circumvent this like so

TEMPLATE_DIRS ('../../../../http://example.com/',)

But it still forces a leading slash, so I get "/http://example.com", which is useless.

My questions:

  1. Is there a way to trick this into pulling the template files from
    another server?

  2. Is that even feasible, given that the template files need to be
    processed for the view?

  3. Is it possible to create an alternate to 'django.template.loaders.filesystem.Loader' that doesn't call for unix style slashes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烟燃烟灭 2024-12-23 22:38:35

如果您不想,则不需要使用模板目录。如果您有一个提供模板文件的服务器,您可以简单地使用 urllib2 远程获取它们,并使用上下文手动创建和渲染模板:

import urllib2
from django.template import Context, Template

tpl_html = urllib2.urlopen("http://mysite.com")
tpl = Template(tpl_html)
return tpl.render(Context({
    'some_variable' : 'some_val',
})

如果您打算这样做,您必须合并一些缓存,对于每个使用此模板的请求,都需要发出外部请求。或者,您可以将其写入自定义加载程序,但它也会受到相同的限制。

You don't need to use the template directory is you dont want to. If you have a server that is serving template files, you can simply fetch them remotely using urllib2 and create and render the template with a context manually:

import urllib2
from django.template import Context, Template

tpl_html = urllib2.urlopen("http://mysite.com")
tpl = Template(tpl_html)
return tpl.render(Context({
    'some_variable' : 'some_val',
})

If you are going to do this, you have to incorporate some caching, as for every request to using this template, you need to make an external request. Alternatively you could write this into a custom loader but it will suffer the same limitations.

南城追梦 2024-12-23 22:38:35

你不能这样做。

它与路径名无关。只是文件系统模板加载器需要从文件系统加载内容,因此得名。

这与 MEDIA_URL 的情况完全不同:MEDIA_URL 只是将路径添加到 HTML 中,然后浏览器会加载该路径。 Django 不关心该文件所在的位置:尽管事实上相反,但如果你向它传递一个不是 URL 的文件路径(即由某处的网络服务器提供服务),它根本无法工作。

现在,您可以编写一个模板加载器,从另一台服务器获取模板。模板加载器是可插入的 - 您只需将新加载器的名称放入 TEMPLATE_LOADERS 设置中即可。加载器本身需要使用 urllib.urlopen 之类的东西从外部服务器获取模板。

但在这样做之前要仔细考虑。这意味着现在每个模板请求都需要调用外部服务器才能提供页面。在扩展其他模板并包含对所包含模板标记的调用的模板的典型情况下,可能有五次或十次调用。而且,与媒体文件不同,它不能并行完成:在整个过程完成之前不会提供页面。这可能会使您的网络服务器变得非常非常慢。

我不知道你为什么认为你需要这样做。模板是应用程序代码的一部分,因此它们通常与 Python 代码位于同一服务器上。如果您确实有某种原因将它们保留在外部,一种解决方案可能是通过 sshfs。但它仍然可能非常慢。再想一想。

You can't do this.

It has nothing to do with path names. It's just that the filesystem template loader needs to load things from the filesystem, hence the name.

This is completely different from the case of MEDIA_URL: that simply adds a path into your HTML, which your browser then loads. Django doesn't care where that file lives: although in fact the opposite applies, in that if you pass it a filepath that isn't a URL (ie served by a webserver somewhere), it simply won't work.

Now, you could write a template loader that gets its templates from another server. Template loaders are pluggable - you just need to put the name of your new loader in the TEMPLATE_LOADERS setting. The loader itself would need to use something like urllib.urlopen to get the template from the external server.

But think very carefully before you do this. This means that every single template request now requires a call to an external server before you can serve the page. In the typical case of a template that extends other templates and includes calls to included template tags, that might be five or ten calls. And, unlike media files, it can't be done in parallel: the page simply won't be served until the whole process is finished. This is likely to make your webserver very very slow.

I don't know why you think you need to do this. Templates are part of your application code, so they would normally live on the same server as your Python code. If you really have some reason to keep them externally, one solution might be to mount the external filesystem onto your webserver via something like sshfs. It's still likely to be very slow though. Think again.

诗笺 2024-12-23 22:38:35
  1. 否 - 不可能欺骗它通过 http 从另一台服务器拉取文件
  2. 是 - 你当然可以子类 django.template.loaders.filesystem.Loader (并通过适当地改变 load_template_source 方法),以便你可以通过 http 加载模板

一旦你完成了 3 那么 2 的答案是肯定的 - 这是可行的 - 最终 Django 的模板语言并不关心它从哪里获取文件,只要它的格式正确即可。

然而,这似乎是一种非常低效的加载模板的方法,并且更有可能有更好的方法来实现相同的结果。

  1. No - it's not possible to trick it into pulling files from another server via http
  2. Yes - you certainly could subclass django.template.loaders.filesystem.Loader (and by altering the load_template_source method appropriately) so that you could load templates via http

Once you had done 3 then the answer to 2 would be yes - it would be feasible - ultimately Django's template language doesn't care where it gets the file from, as long it's in the right format.

However, it seems like a very inefficient way of loading templates and more likely there is a much better way of achieving the same result.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文