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 管理命令在每次运行后调用 STORAGESstaticfiles 存储后端的 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

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

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

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

注释中的引用

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

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 应用之外,还有一些其他辅助程序可用于处理静态文件

静态文件开发视图

静态文件工具主要旨在帮助成功将静态文件部署到生产环境中。这通常意味着一个单独的专用静态文件服务器,这在本地开发时会带来很多开销。因此,staticfiles 应用附带了一个**快速简便的辅助视图**,您可以使用它在本地开发环境中提供服务文件。

views.serve(request, path)

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

警告

只有当 DEBUGTrue 时,此视图才有效。

这是因为此视图**效率极低**,并且可能**不安全**。这仅适用于本地开发,**绝不应在生产环境中使用**。

注意

为了猜测已提供文件的 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 知道在哪里查找文件(除了应用程序目录中的文件)。

警告

只有当 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

返回顶部