在Django中如何在视图中获取静态文件的URL

168

我正在使用reportlab pdfgen创建PDF。在PDF中,有一个由drawImage创建的图像。为此,我需要图像的URL或视图中图像的路径。我已经成功构建了URL,但如何获取图像的本地路径?

如何获取URL:

prefix = 'https://' if request.is_secure() else 'http://'
image_url = prefix + request.get_host() + STATIC_URL + "images/logo_80.png"
8个回答

337
# Older Django <3.0 (also deprecated in 2.0):
from django.contrib.staticfiles.templatetags.staticfiles import static

# Django 3.0+
from django.templatetags.static import static

url = static('x.jpg')

URL现在包含'/static/x.jpg',假设静态路径为'/static/'


2
你知道是否有一种简洁的方法将主机名添加到静态URL中(如果STATIC_URL中不存在)吗? 我需要在邮件中添加图像或其他资源,用户无法使用相对URL找到这些资源。 - gepatino
5
在 Debug 模式下这对我不起作用(尚未尝试 DEBUG=False)。我只是得到传递给静态方法的路径返回。使用 Django 1.6。有什么想法吗? - Shawn
2
对于和@Shawn(或我)遇到相同问题的任何人,这可能是因为您提供了以斜杠开头的路径。不要使用static('/style.css'),而应该使用static('style.css') - Djizeus
32
在Django 2.0中,这将显示一个弃用通知。请改用from django.templatetags.static import static - Flimm
1
@Anupam,你可能将'/static'添加到了static函数的参数中,这是不正确的。请尝试使用static('my_file_name.xlsx') - shad0w_wa1k3r
显示剩余5条评论

94

编辑:如果您使用的是Django >=3.0,请参考在Django中获取视图中静态文件的URL,本问题答案适用于Django 1.X版本。

dyve的回答很好,但是,如果您在django项目中使用了“缓存存储”,并且静态文件的最终url路径应该被“哈希”(例如从style.css生成的style.aaddd9d8d8d7.css),那么您不能通过django.templatetags.static.static()得到精确的url。相反,您必须使用django.contrib.staticfiles中的模板标签来获取哈希的url。

此外,在使用开发服务器时,此模板标签方法返回非哈希的url,因此您可以无论它是开发还是生产主机都可以使用此代码! :)

from django.contrib.staticfiles.templatetags.staticfiles import static

# 'css/style.css' file should exist in static path. otherwise, error will occur 
url = static('css/style.css')

1
谢谢这个...花了我一段时间才弄清楚为什么我没有注入我的MD5哈希值。 - ilovett
4
这个回答仍在受到关注并被积极使用,因此我在给@Kenial致谢的前提下改进了我的已被接受的答案。这仍然是解决这个问题的首选方案。 - dyve
1
在Django 3.2中,django.contrib.staticfiles中没有templatetags。请参见https://dev59.com/l2gt5IYBdhLWcg3w7BkE#59355195。 - dfrankow
@dfrankow 看起来我是在 Django 1.3 的某个地方回答了这个问题...哇,已经过了好久了。感谢您的改进! - Kenial

35
从Django 3.0开始,您应该使用from django.templatetags.static import static
from django.templatetags.static import static

...

img_url = static('images/logo_80.png')

然后在您的模板中使用<img src="{{img_url}}" alt="img_url"> - Artur

15

这里有另一种方法!(在Django 1.6上测试通过)

from django.contrib.staticfiles.storage import staticfiles_storage
staticfiles_storage.url(path)

如果将 DEBUG 设置为 False,则此解决方案将返回已哈希的 URL,也可以选择强制使用哈希的 URL,如下所示:staticfiles_storage.url(path, force=True) - Marc Gibbons

11

使用默认的static标签:

from django.templatetags.static import static
static('favicon.ico')

django.contrib.staticfiles.templatetags.staticfiles中还有另一个标签(如被接受的答案中所示),但在Django 2.0+中已被弃用。


为什么我会在开头得到斜杠“/static”,即使我从未在开头添加斜杠? - AnonymousUser

8

@dyve 的答案在我的开发服务器上没有生效。相反,我使用了 find 解决了问题。以下是函数:

from django.conf import settings
from django.contrib.staticfiles.finders import find
from django.templatetags.static import static

def get_static(path):
    if settings.DEBUG:
        return find(path)
    else:
        return static(path)

7
如果您想获取绝对URL(包括协议,主机和端口),则可以使用如下所示的request.build_absolute_uri函数:
from django.contrib.staticfiles.storage import staticfiles_storage
self.request.build_absolute_uri(staticfiles_storage.url('my-static-image.png'))
# 'http://localhost:8000/static/my-static-image.png'

0

简单来说,您需要正确设置以下内容:

  • STATIC_URL
  • STATIC_ROOT
  • urlpatterns
  • staticfiles
  • templatetags
  • url参数

只有这些设置都正确无误,才能使程序正常运行。此外,在实时部署中,情况各不相同,很可能您在本地机器上花费3个小时设置好的内容,在服务器上却无法正常工作。

因此,我采用了传统的方式!

app
├── static
│   └── json
│       └── data.json
└── views.py

views.py

import os

with open(os.path.abspath(os.getcwd()) + '/app/static/json/data.json', 'r') as f:
    pass

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