staticfiles 应用

django.contrib.staticfiles 从你的每个应用程序(以及你指定的任何其他地方)收集静态文件到一个位置,以便在生产环境中轻松提供服务。

另请参阅

有关静态文件应用的简介和一些使用示例,请参阅 如何管理静态文件(例如图像、JavaScript、CSS)。有关部署静态文件的指南,请参阅 如何部署静态文件

管理命令

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 管理命令在每次运行后调用 post_process() 方法,该方法来自 STORAGES 中的 staticfiles 存储后端,并传递管理命令找到的路径列表。它还接收 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

在尝试复制或链接原始文件之前,清除现有文件。

创建到每个文件的符号链接,而不是复制。

--no-post-process

不调用 post_process() 方法,该方法来自 STORAGES 中配置的 staticfiles 存储后端。

--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

存储。StaticFilesStorage

一个 FileSystemStorage 存储后端的子类,使用 STATIC_ROOT 设置作为基本文件系统位置,并分别使用 STATIC_URL 设置作为基本 URL。

存储。StaticFilesStorage.后处理(路径, **选项)

如果在存储上定义了此方法,则在每次运行后由 collectstatic 管理命令调用它,并将找到的文件的本地存储和路径作为字典以及命令行选项传递给它。它产生三个值元组:原始路径, 已处理路径, 已处理。路径值是字符串,已处理 是一个布尔值,表示该值是否已后处理,或者如果后处理失败,则表示异常。

ManifestStaticFilesStorage 在幕后使用它来用哈希对应项替换路径并适当地更新缓存。

ManifestStaticFilesStorage

存储。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");

…将通过调用 url() 方法替换 ManifestStaticFilesStorage 存储后端,最终保存一个 '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)

注释中的引用

ManifestStaticFilesStorage 不会忽略已注释掉的语句中的路径。这 可能会导致不存在的路径崩溃。您应该检查并最终删除注释。

在 Django 4.2 中更改

添加了在 importexport 语句中查找 JavaScript 模块路径的实验性可选支持。

storage.ManifestStaticFilesStorage.manifest_hash
Django 4.2 中的新增功能。

此属性提供了一个哈希值,每当清单中的文件发生更改时,该哈希值就会更改。这对于向 SPA 传达服务器上的资产已更改(由于新部署)非常有用。

storage.ManifestStaticFilesStorage.max_post_process_passes

由于静态文件可能引用其他需要替换路径的静态文件,因此可能需要多次替换路径,直到文件哈希值收敛。为了防止由于哈希值不收敛而导致无限循环(例如,如果 'foo.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 与自定义存储一起使用,以将文件的 MD5 哈希附加到文件名中,就像 ManifestStaticFilesStorage 所做的那样。

查找器模块

staticfiles 查找器具有 searched_locations 属性,该属性是查找器进行搜索的目录路径列表。示例用法

from django.contrib.staticfiles import finders

result = finders.find("css/base.css")
searched_locations = finders.searched_locations

其他帮助器

staticfiles 应用程序外部还有一些其他帮助器可用于处理静态文件

静态文件开发视图

静态文件工具主要设计用于帮助将静态文件成功部署到生产环境中。这通常意味着一个单独的、专用的静态文件服务器,在本地开发时,这会带来很多麻烦。因此,staticfiles 应用程序附带了一个快速而粗糙的帮助程序视图,你可以在开发时使用它在本地提供文件。

views.serve(request, path)

此视图函数在开发中提供静态文件。

警告

此视图仅在 DEBUGTrue

这是因为此视图非常低效,而且可能不安全。这仅适用于本地开发,切勿在生产环境中使用

注意

为了猜测已提供文件的类型,此视图依赖于 Python 标准库中的 mimetypes 模块,而该模块本身依赖于底层平台的映射文件。如果您发现此视图未为某些文件返回正确的类型,则很可能是平台的映射文件不正确或需要更新。例如,可以通过在 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 知道除了应用程序目录中的文件之外,还可以在哪里查找文件。

警告

此帮助程序函数仅在 DEBUGTrue 且您的 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

返回顶部