Django获取静态文件的绝对路径

27
在Django中,当我使用以下代码时:

{{ request.build_absolute_uri }}{% static "img/myimage.jpg" %}

它生成的是:'http://myurl.com//static/img/myimage.jpg'。这会产生一个错误。

我该如何去掉双斜杠?

静态URL为:

STATIC_URL = '/static/'

但我认为去掉第一个 '/' 不是一个好主意。

4
你能不能简单地去掉 {% static "img/myimage.jpg" %}?你真的需要在那里使用 {{ request.build_absolute_uri }} 吗? - janos
5
我需要访问完整路径。 - cusejuice
我使用 request.build_absolute_uri().rstrip('/') 并将其作为上下文变量传递到我的模板。 - Vassilis
7个回答

26

request对象可以在您的模板中使用,您可以轻松访问属性,例如request.schemerequest.META.HTTP_HOST,以构建可在静态URL前附加的基本URL,从而获取完整的URL。

最终示例将类似于以下内容:

<img src="{{request.scheme}}://{{request.META.HTTP_HOST}}{% static 'img/myimage.jpg' %}">

19

build_absolute_uri 方法为当前页面构建一个绝对URI。这意味着,如果您在例如 'http://myurl.com/login/' 页面,生成的完整URL将是 'http://myurl.com/login//static/img/myimage.jpg'。

相反,使用 request.get_host() (可选与 request.scheme 一起使用以获取URL方案),或更好地,使用站点框架来设置模板变量到当前站点域名。关于代理,get_host()方法存在一些问题

get_host() 方法将返回当前域名,未附加路径。


7
你能提供完整的例子吗? - Seif
3
这里有一个带有 schemeget_host 的例子。 <meta property="og:image" content="{% block og_image %}{{ request.scheme }}://{{ request.get_host }}{% static 'vitrine/images/logo-open-graph.png' %}{% endblock %}" /> 由于 // 的原因,无法使用 build_absolute_uri 让它正常工作。 - Vadorequest

7

我刚刚为此创建了一个快速模板标签。如果您还没有它们,请创建文件/myapp/templatetags/__init__.py/myapp/templatetags/my_tag_library.py,并将以下内容添加到my_tag_library.py中:

from django import template
from django.templatetags import static

register = template.Library()

class FullStaticNode(static.StaticNode):
    def url(self, context):
        request = context['request']
        return request.build_absolute_uri(super().url(context))


@register.tag('fullstatic')
def do_static(parser, token):
    return FullStaticNode.handle_token(parser, token)

然后在你的模板中,只需输入{% load my_tag_library %},然后使用例如{% fullstatic my_image.jpg %}

对于之前评论中对为什么有人需要这样做的疑问的回应,我特别的用例是想将静态文件的链接放在开放图谱协议元标记内部,并且这些链接需要是绝对路径。在开发中,静态文件是本地提供服务的,但在生产中,它们会远程提供服务,因此我不能简单地添加主机名以获取完整的URL。


这正是我正在寻找的。 - lmiguelvargasf
对于使用Python 2.7的任何人,我必须将超级部分编写为super(FullStaticNode, self).url(context) - Kirkman14

2
使用这个来制作应用程序:

{{ request.build_absolute_uri|slice:":-1" }}{% static "img/myimage.jpg" %}

通常情况下使用此功能:

{{ request.scheme }}://{{ request.META.HTTP_HOST }}{% static "img/myimage.jpg" %}

1

这个是否值得更新(Django 2+)?

这对我特别有帮助,因为我正在尝试在链接中放置一个查询,即myimage.jpg实际上是从数据库中提取的。我需要一种将其放入src中的方法,即用{{ img_link_field_in_model }}替换'myimage.jpg'。

<img src="{% get_static_prefix %}img/myimage.jpg">

将会产生:

<img src="/static/img/myimage.jpg">

查询示例如下:
<img src="{% get_static_prefix %}img/{{img_link_from_model}}">

-4

不太确定你在问什么,但是由于 {% static .. %} 只是在你指定的路径前面添加了 /static/,你可以自己这样做:

{{ request.build_absolute_uri }}static/img/myimage.jpg

不是非常模块化,但大多数情况下你不需要直接访问完整的URL,因为如果你将其用作某个HTML对象的src,它只会将其附加到你所在的任何URL上。


他想知道如何去掉第二个斜杠,假设不绕过静态框架。 - Yuji 'Tomita' Tomita

-6

build_absolute_uri 接受位置作为参数,可以处理双斜杠问题。不幸的是,您无法通过 Django 模板语言传递参数。

您需要构建一个自定义模板标签或过滤器,该标签或过滤器接受 build_absolute_uri 函数的参数。

我喜欢 Jinja 的其中一个原因就是我可以这样做:

{{ request.build_absolute_uri(static('img/foo.png')) }}

这是错误的。你确实可以使用Django模板语言传递参数,例如 {% url 'some-url-name' arg1=v1 arg2=v2 %} 来源 - Erik Kalkoken

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接