staticfiles
应用¶
django.contrib.staticfiles
收集来自各个应用程序(以及您指定的任何其他位置)的静态文件,并将它们集中到一个位置,以便在生产环境中轻松提供服务。
另请参见
有关静态文件应用程序的介绍和一些使用示例,请参见 如何管理静态文件(例如图像、JavaScript、CSS)。有关部署静态文件的指南,请参见 如何部署静态文件。
设置¶
有关以下设置的详细信息,请参见 staticfiles 设置
管理命令¶
django.contrib.staticfiles
提供三个管理命令。
collectstatic
¶
- django-admin collectstatic¶
将静态文件收集到 STATIC_ROOT
。
默认情况下,重复的文件名解析方式类似于模板解析:首先在一个指定位置找到的文件将被使用。如果您感到困惑,findstatic
命令可以帮助您查看找到哪些文件。
在后续的 collectstatic
运行中(如果 STATIC_ROOT
不为空),只有当文件的修改时间戳大于 STATIC_ROOT
中文件的时戳时,才会复制文件。因此,如果您从 INSTALLED_APPS
中删除一个应用程序,最好使用 collectstatic --clear
选项删除过时的静态文件。
通过使用 enabled finders
搜索文件。默认情况下,会在 STATICFILES_DIRS
中定义的所有位置以及 INSTALLED_APPS
设置指定的应用程序的 'static'
目录中查找。
collectstatic
管理命令在每次运行后调用 STORAGES
中 staticfiles
存储后端的 post_process()
方法,并传递管理命令已找到的路径列表。它还会接收 collectstatic
的所有命令行选项。默认情况下, ManifestStaticFilesStorage
使用此功能。
默认情况下,收集的文件将从 FILE_UPLOAD_PERMISSIONS
接收权限,收集的目录将从 FILE_UPLOAD_DIRECTORY_PERMISSIONS
接收权限。如果您希望这些文件和/或目录具有不同的权限,您可以对 静态文件存储类 中的任何一个进行子类化,并分别指定 file_permissions_mode
和/或 directory_permissions_mode
参数。例如
from django.contrib.staticfiles import storage
class MyStaticFilesStorage(storage.StaticFilesStorage):
def __init__(self, *args, **kwargs):
kwargs["file_permissions_mode"] = 0o640
kwargs["directory_permissions_mode"] = 0o760
super().__init__(*args, **kwargs)
然后在 STORAGES
设置中将 staticfiles
存储后端设置为 'path.to.MyStaticFilesStorage'
。
一些常用的选项是
- --noinput, --no-input¶
不要提示用户输入任何内容。
- --ignore PATTERN, -i PATTERN¶
忽略与该 glob 样式模式匹配的文件、目录或路径。多次使用以忽略更多内容。指定路径时,即使在 Windows 上也始终使用正斜杠。
- --dry-run, -n¶
执行所有操作,但不会修改文件系统。
- --clear, -c¶
在尝试复制或链接原始文件之前清除现有文件。
- --link, -l¶
创建指向每个文件的符号链接,而不是复制。
- --no-post-process¶
不要调用
STORAGES
中配置的staticfiles
存储后端的post_process()
方法。
- --no-default-ignore¶
不要忽略常见的私有 glob 样式模式
'CVS'
、'.*'
和'*~'
。
有关选项的完整列表,请运行以下命令以查看命令自身帮助:
$ python manage.py collectstatic --help
...\> py manage.py collectstatic --help
自定义忽略模式列表¶
默认忽略模式列表,['CVS', '.*', '*~']
,可以以比每次collectstatic
调用都提供--ignore
命令选项更持久的方式进行自定义。提供一个自定义的AppConfig
类,重写此类的ignore_patterns
属性,并在你的INSTALLED_APPS
设置中用该类路径替换'django.contrib.staticfiles'
。
from django.contrib.staticfiles.apps import StaticFilesConfig
class MyStaticFilesConfig(StaticFilesConfig):
ignore_patterns = [...] # your custom ignore list
findstatic
¶
- django-admin findstatic staticfile [staticfile ...]¶
使用已启用的查找器搜索一个或多个相对路径。
例如
$ python manage.py findstatic css/base.css admin/js/core.js
Found 'css/base.css' here:
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
Found 'admin/js/core.js' here:
/home/polls.com/src/django/contrib/admin/media/js/core.js
...\> py manage.py findstatic css\base.css admin\js\core.js
Found 'css/base.css' here:
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
Found 'admin/js/core.js' here:
/home/polls.com/src/django/contrib/admin/media/js/core.js
- findstatic --first¶
默认情况下,会找到所有匹配的位置。若要仅返回每个相对路径的第一个匹配项,请使用--first
选项。
$ python manage.py findstatic css/base.css --first
Found 'css/base.css' here:
/home/special.polls.com/core/static/css/base.css
...\> py manage.py findstatic css\base.css --first
Found 'css/base.css' here:
/home/special.polls.com/core/static/css/base.css
这是一个调试辅助工具;它将准确显示将为给定路径收集哪个静态文件。
通过将--verbosity
标志设置为0,您可以抑制额外输出,只获取路径名称。
$ python manage.py findstatic css/base.css --verbosity 0
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
...\> py manage.py findstatic css\base.css --verbosity 0
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
另一方面,通过将--verbosity
标志设置为2,您可以获取所有已搜索的目录。
$ python manage.py findstatic css/base.css --verbosity 2
Found 'css/base.css' here:
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
Looking in the following locations:
/home/special.polls.com/core/static
/home/polls.com/core/static
/some/other/path/static
...\> py manage.py findstatic css\base.css --verbosity 2
Found 'css/base.css' here:
/home/special.polls.com/core/static/css/base.css
/home/polls.com/core/static/css/base.css
Looking in the following locations:
/home/special.polls.com/core/static
/home/polls.com/core/static
/some/other/path/static
runserver
¶
- django-admin runserver [addrport]
如果staticfiles
应用已安装
,则会覆盖核心runserver
命令,并添加静态文件的自动服务功能。文件服务不会通过MIDDLEWARE
运行。
该命令添加了以下选项:
- --nostatic¶
使用--nostatic
选项可以完全禁用使用staticfiles应用提供静态文件的功能。只有当staticfiles应用位于你的项目INSTALLED_APPS
设置中时,此选项才可用。
使用方法示例:
$ django-admin runserver --nostatic
...\> django-admin runserver --nostatic
- --insecure¶
使用--insecure
选项可以强制使用staticfiles应用提供静态文件,即使DEBUG
设置为False
。使用此选项表示您承认它**效率极低**,并且可能**不安全**。这仅用于本地开发,**绝不应在生产环境中使用**,并且只有当staticfiles应用位于你的项目INSTALLED_APPS
设置中时才可用。
--insecure
不能与ManifestStaticFilesStorage
一起使用。
使用方法示例:
$ django-admin runserver --insecure
...\> django-admin runserver --insecure
存储¶
StaticFilesStorage
¶
- class storage.StaticFilesStorage¶
这是一个FileSystemStorage
存储后端的子类,它使用STATIC_ROOT
设置作为基本文件系统位置,并分别使用STATIC_URL
设置作为基本URL。
- storage.StaticFilesStorage.post_process(paths, **options)¶
如果在存储上定义了此方法,则collectstatic
管理命令在每次运行后都会调用它,并将其作为字典传递给本地存储和找到文件的路径,以及命令行选项。它会生成包含三个值的元组:original_path, processed_path, processed
。路径值是字符串,processed
是一个布尔值,指示该值是否经过后处理,或者如果后处理失败则为异常。
ManifestStaticFilesStorage
在后台使用它来用其哈希后的副本替换路径,并适当地更新缓存。
ManifestStaticFilesStorage
¶
- class storage.ManifestStaticFilesStorage¶
这是一个StaticFilesStorage
存储后端的子类,它通过将文件的 MD5 哈希值附加到文件名来存储它处理的文件名。例如,文件css/styles.css
也会保存为css/styles.55e7cbb9ba48.css
。
此存储的目的是在某些页面仍然引用这些文件的情况下(例如,因为它们被您或第三方代理服务器缓存)继续提供旧文件服务。此外,如果您想对已部署的文件应用远期 Expires 标头以加快后续页面访问的加载时间,它非常有用。
存储后端会自动将保存在保存的文件中与其他保存的文件匹配的路径替换为缓存副本的路径(使用post_process()
方法)。用于查找这些路径的正则表达式(django.contrib.staticfiles.storage.HashedFilesMixin.patterns
)涵盖:
如果您想使用实验性正则表达式来涵盖以下内容,请子类化ManifestStaticFilesStorage
并将support_js_module_import_aggregation
属性设置为True
:
例如,具有以下内容的'css/styles.css'
文件:
@import url("../admin/css/base.css");
……将通过调用ManifestStaticFilesStorage
存储后端的url()
方法来替换,最终保存一个'css/styles.55e7cbb9ba48.css'
文件,其内容如下:
@import url("../admin/css/base.27e20196a850.css");
使用带本地文件的integrity
HTML 属性
当在诸如<script>
或<link>
之类的标记中使用可选的integrity
属性时,其值应根据文件的提供方式计算,而不是根据存储在文件系统中的方式计算。这尤其重要,因为根据静态文件的收集方式,其校验和可能会发生更改(例如,当使用collectstatic
时)。目前,还没有为此提供现成的工具。
您可以通过使用自定义的 ManifestStaticFilesStorage
子类并设置 manifest_storage
参数来更改清单文件的位置。例如
from django.conf import settings
from django.contrib.staticfiles.storage import (
ManifestStaticFilesStorage,
StaticFilesStorage,
)
class MyManifestStaticFilesStorage(ManifestStaticFilesStorage):
def __init__(self, *args, **kwargs):
manifest_storage = StaticFilesStorage(location=settings.BASE_DIR)
super().__init__(*args, manifest_storage=manifest_storage, **kwargs)
- storage.ManifestStaticFilesStorage.manifest_hash¶
此属性提供一个单一哈希值,只要清单中的文件发生更改,它就会发生变化。这对于向 SPA 传达服务器上的资产已更改(由于新的部署)非常有用。
- storage.ManifestStaticFilesStorage.max_post_process_passes¶
由于静态文件可能引用需要替换其路径的其他静态文件,因此可能需要多次替换路径才能使文件哈希收敛。为了防止由于哈希不收敛而导致无限循环(例如,如果 'foo.css'
引用 'bar.css'
,而 'bar.css'
又引用 'foo.css'
),在放弃后处理之前,最多只能进行一定次数的传递。在引用数量很大的情况下,可能需要更多次的传递。通过子类化 ManifestStaticFilesStorage
并设置 max_post_process_passes
属性来增加最大传递次数。默认值为 5。
要启用 ManifestStaticFilesStorage
,您必须确保满足以下要求
STORAGES
设置中的staticfiles
存储后端设置为'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
DEBUG
设置设置为False
您已使用
collectstatic
管理命令收集所有静态文件
由于在运行时创建 MD5 哈希可能会给您的网站带来性能负担,因此 staticfiles
将自动在一个名为 staticfiles.json
的文件中存储所有已处理文件的哈希名称映射。当您运行 collectstatic
管理命令时,此操作会执行一次。
- storage.ManifestStaticFilesStorage.manifest_strict¶
如果在运行时未在 staticfiles.json
清单中找到文件,则会引发 ValueError
。可以通过子类化 ManifestStaticFilesStorage
并将 manifest_strict
属性设置为 False
来禁用此行为——不存在的路径将保持不变。
由于需要运行 collectstatic
,因此在运行测试时通常不应使用此存储,因为 collectstatic
不是正常测试设置的一部分。在测试期间,确保 STORAGES
设置中的 staticfiles
存储后端设置为其他内容,例如 'django.contrib.staticfiles.storage.StaticFilesStorage'
(默认值)。
- storage.ManifestStaticFilesStorage.file_hash(name, content=None)¶
创建文件哈希名称时使用的方法。需要为给定的文件名和内容返回一个哈希值。默认情况下,它会根据上面提到的内容的块计算 MD5 哈希值。您可以随意覆盖此方法以使用您自己的哈希算法。
ManifestFilesMixin
¶
- class storage.ManifestFilesMixin¶
将此 mixin 与自定义存储一起使用,以便像 ManifestStaticFilesStorage
一样,将文件的 MD5 哈希值追加到文件名中。
查找器模块¶
staticfiles
查找器具有 searched_locations
属性,这是一个查找器搜索过的目录路径列表。使用示例
from django.contrib.staticfiles import finders
result = finders.find("css/base.css")
searched_locations = finders.searched_locations
其他辅助程序¶
除了 staticfiles
应用之外,还有一些其他辅助程序可用于处理静态文件
django.template.context_processors.static()
上下文处理器,它将STATIC_URL
添加到使用RequestContext
上下文呈现的每个模板上下文中。内置模板标签
static
,它接受一个路径并将其与静态前缀STATIC_URL
使用 urljoin 连接。如果安装了django.contrib.staticfiles
,则该标签会使用STORAGES
中staticfiles
存储后端的url()
方法。内置模板标签
get_static_prefix
,它使用静态前缀STATIC_URL
填充模板变量,以便用作变量或直接使用。类似的模板标签
get_media_prefix
,其工作方式类似于get_static_prefix
,但使用MEDIA_URL
。django.core.files.storage.storages
中的staticfiles
键包含一个可立即使用的静态文件存储后端实例。
静态文件开发视图¶
静态文件工具主要旨在帮助成功将静态文件部署到生产环境中。这通常意味着一个单独的专用静态文件服务器,这在本地开发时会带来很多开销。因此,staticfiles
应用附带了一个**快速简便的辅助视图**,您可以使用它在本地开发环境中提供服务文件。
- views.serve(request, path)¶
此视图函数在开发环境中提供静态文件服务。
注意
为了猜测已提供文件的 MIME 类型,此视图依赖于 Python 标准库中的 mimetypes
模块,该模块本身依赖于底层平台的映射文件。如果您发现此视图未为某些文件返回正确的 MIME 类型,则很可能是平台的映射文件不正确或需要更新。例如,这可以通过在 Red Hat 发行版上安装或更新 mailcap
包,在 Debian 发行版上安装或更新 mime-support
包,或编辑 Windows 注册表中 HKEY_CLASSES_ROOT
下的键来实现。
此视图由 runserver
自动启用(DEBUG
设置为 True
)。要在不同的本地开发服务器上使用此视图,请将以下代码片段添加到主 URL 配置的末尾
from django.conf import settings
from django.contrib.staticfiles import views
from django.urls import re_path
if settings.DEBUG:
urlpatterns += [
re_path(r"^static/(?P<path>.*)$", views.serve),
]
注意,模式的开头 (r'^static/'
) 应为您的 STATIC_URL
设置。
由于这有点棘手,还有一个辅助函数可以为您完成此操作
- urls.staticfiles_urlpatterns()¶
这将返回用于向您已定义的模式列表提供静态文件的正确 URL 模式。使用方法如下:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# ... the rest of your URLconf here ...
urlpatterns += staticfiles_urlpatterns()
这将检查您的 STATIC_URL
设置,并连接视图以相应地提供静态文件。请勿忘记适当地设置 STATICFILES_DIRS
设置,以使 django.contrib.staticfiles
知道在哪里查找文件(除了应用程序目录中的文件)。
警告
只有当 DEBUG
为 True
并且您的 STATIC_URL
设置既不是空值也不是完整的 URL(例如 http://static.example.com/
)时,此辅助函数才有效。
这是因为此视图**效率极低**,并且可能**不安全**。这仅适用于本地开发,**绝不应在生产环境中使用**。
支持“实时测试”的专用测试用例¶
- class testing.StaticLiveServerTestCase¶
此 unittest TestCase 子类扩展了 django.test.LiveServerTestCase
。
与其父类一样,您可以使用它来编写涉及运行被测代码并通过 HTTP(例如 Selenium、PhantomJS 等)使用测试工具使用它的测试,因此需要发布静态资源。
但鉴于它使用了上面描述的 django.contrib.staticfiles.views.serve()
视图,它可以在测试执行时透明地覆盖 staticfiles
查找器提供的资源。这意味着您无需在测试设置之前或作为测试设置的一部分运行 collectstatic
。
注释中的引用
ManifestStaticFilesStorage
不会忽略注释掉的语句中的路径。这 可能会在不存在的路径上崩溃。您应该检查并最终去除注释。