# Django 3.2.11.dev 文档

# `staticfiles` 应用

`django.contrib.staticfiles` 从你的每一个应用程序（以及你指定的任何其他地方）收集静态文件到一个单一的位置，可以很容易地在生产中服务。

参见

关于静态文件应用的介绍和一些使用示例，请参见 管理静态文件（比如图片、JavaScript、CSS）。关于部署静态文件的指南，请参见 部署静态文件。

## 配置

关于以下配置，请参见 静态文件配置：

- `STATIC_ROOT`
- `STATIC_URL`
- `STATICFILES_DIRS`
- `STATICFILES_STORAGE`
- `STATICFILES_FINDERS`

## 管理命令

`django.contrib.staticfiles` 公开了三个管理命令。

### `collectstatic`

`django-admin collectstatic`

将静态文件收集到 `STATIC_ROOT` 中。

重复的文件名默认的解析方式与模板解析的方式类似：首先在指定位置找到的文件将被使用。如果你感到困惑， `findstatic` 命令可以帮助你显示哪些文件被找到。

在随后运行 `collectstatic` 时（如果 `STATIC_ROOT` 不是空的），只有当文件的修改时间戳大于 `STATIC_ROOT` 中文件的时间戳时，才会被复制。因此，如果你从 `INSTALLED_APPS` 中删除一个应用程序，最好使用 `collectstatic --clear` 选项来删除过时的静态文件。

通过使用 `启用的查找器` 搜索文件。默认情况是在 `STATICFILES_DIRS` 中定义的所有位置和 `INSTALLED_APPS` 配置指定的应用程序的 `'static'` 目录中查找。

`collectstatic` 管理命令在每次运行后都会调用 `STATICFILES_STORAGE` 中的 `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)

然后将 `STATICFILES_STORAGE` 设置为 `'path.to.MyStaticFilesStorage'`。

一些常用的选项是：

`--noinput````,` `--no-input```

  不要提示用户进行任何形式的输入。

`--ignore` `PATTERN``,` `-i` `PATTERN`

  忽略与此 glob 样式模式匹配的文件、目录或路径。多次使用可以忽略更多的文件、目录或路径。当指定路径时，始终使用正斜线，即使在 Windows 上也是如此。

`--dry-run````,` `-n```

  除了修改文件系统外，其他都要做。

`--clear````,` `-c```

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

`--link````,` `-l```

  为每个文件创建一个符号链接，而不是复制。

`--no-post-process```

  不要调用配置的 `STATICFILES_STORAGE` 存储后端的 `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` 应用程序被 `installed`，则覆盖核心 `runserver` 命令，并增加静态文件的自动服务。文件服务不通过 `MIDDLEWARE` 运行。

该命令增加了这些选项：

`--nostatic```

使用 `--nostatic` 选项来完全禁止使用 静态文件 应用程序提供静态文件。只有当 静态文件 应用在你的项目的 `INSTALLED_APPS` 配置中时，这个选项才可用。

使用实例：

/ 

    $ django-admin runserver --nostatic

    ...\> django-admin runserver --nostatic

`--insecure```

使用 `--insecure` 选项来强制使用 静态文件 应用服务静态文件，即使 `DEBUG` 设置为 `False`。通过使用这个选项，你承认了这样的事实，即这是 效率低下的，而且可能是 不安全的。这仅用于本地开发，不应在生产中使用，并且只有当 静态文件 应用在你的项目的 `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`。

这个存储的目的是为了继续服务于旧文件，以防某些页面仍然引用这些文件，例如，因为它们被你或第三方代理服务器缓存了。此外，如果你想在部署的文件上应用 远期失效头信息 ，以加快后续页面访问的加载时间，它是非常有用的。

存储后台会自动将保存文件中找到的与其他保存文件相匹配的路径替换为缓存副本的路径（使用 `post_process()` 方法）。用于查找这些路径的正则表达式（`django.contrib.staticfiles.storage.HashedFilesMixin.patterns`）默认涵盖了 @import 规则和 url() 语句的 层叠样式表 。例如，`''css/styles.css'` 文件的内容为

    @import url("../admin/css/base.css");

会通过调用 `ManifestStaticFilesStorage` 存储后台的 `url()` 方法来替换，最终保存一个 `'css/styles.55e7cbb9ba48.css'` 文件，内容如下：

    @import url("../admin/css/base.27e20196a850.css");

`storage.ManifestStaticFilesStorage.``max_post_process_passes`

由于静态文件可能会引用其他需要替换路径的静态文件，因此可能需要多次替换路径，直到文件哈希值收敛。为了防止由于哈希值不收敛而导致无限循环（例如，如果 `'foo.css'` 引用 `'bar.css'`，而后者引用 `'foo.css'`），在放弃后处理之前有一个最大的传递次数。在引用数量较多的情况下，可能需要更多的传递次数。通过子类 `ManifestStaticFilesStorage` 并设置 `max_post_process_passes` 属性来增加最大传递次数。默认值为 5。

要启用 `ManifestStaticFilesStorage`，你必须确保满足以下要求：

- `STATICFILES_STORAGE` 设置为 `'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` 并不是作为正常测试配置的一部分来运行的。在测试过程中，确保将 `STATICFILES_STORAGE` 设置为类似 `'django.contrib.staticfiles.storage.StaticFilesStorage'` （默认）这样的其他配置。

`storage.ManifestStaticFilesStorage.``file_hash`(name, content=None)

创建文件的哈希名时使用的方法。需要返回给定文件名和内容的哈希值。默认情况下，它从上面提到的内容块中计算出一个 MD5 哈希。可以随意覆盖这个方法，使用自己的哈希算法。

### `ManifestFilesMixin`

class `storage.``ManifestFilesMixin`

使用这个混入和一个自定义的存储来附加文件内容的 MD5 哈希到文件名中，就像 `ManifestStaticFilesStorage` 那样。

## 查找器模块

`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()` 上下文处理器，它为每个用 `RequestContext` 上下文渲染的模板上下文添加 `STATIC_URL`。
- 内置的模板标签 `static`，它接收一个路径，并用静态前缀 `STATIC_URL` 将其连接起来。如果安装了 `django.contrib.staticfiles`，则该标签使用 `STATICFILES_STORAGE` 的 `url()` 方法。
- 内置的模板标签 `get_static_prefix`，将静态前缀 `STATIC_URL` 填充到模板变量中，作为变量或直接使用。
- 类似的模板标签 `get_media_prefix`，其工作原理与 `get_static_prefix` 类似，但使用 `MEDIA_URL`。

### 静态文件开发视图

静态文件工具主要是为了帮助将静态文件成功部署到生产中。这通常意味着一个单独的、专用的静态文件服务器，这在本地开发时是一个很大的开销。因此，`staticfiles` 应用程序中附带了一个 快速和肮脏的辅助视图，你可以在开发中使用它在本地服务文件。

`views.``serve`(request, path)

该视图功能服务于开发中的静态文件。

警告

只有当 `DEBUG` 为 `True` 时，该视图才会生效。

这是因为这个视图的 效率很低，而且可能 不安全。这只用于本地开发，不应该用于生产。

注解

为了猜测服务文件的内容类型，这个视图依赖于 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` 知道除了应用程序目录中的文件外，还可以在哪里查找文件。

警告

只有当 `DEBUG` 是 `True`，并且你的 `STATIC_URL` 的配置既不是空的，也不是完整的 URL，比如 `http://static.example.com/`，这个辅助函数才会起作用。

这是因为这个视图的 效率很低，而且可能 不安全。这只用于本地开发，不应该用于生产。

### 支持“实时测试”的专门测试案例

class `testing.``StaticLiveServerTestCase`

这个 untest TestCase 子类扩展了 `django.test.LiveServerTestCase`。

就像它的父类一样，你可以用它来编写测试，涉及到运行被测代码，并通过 HTTP 与测试工具（如 Selenium、PhantomJS 等）进行消费，因为这需要静态资产也被发布。

但是由于它使用了上面描述的 `django.contrib.staticfiles.views.service()` 视图，它可以在测试执行时透明地叠加 `staticfiles` 查找器提供的资产。这意味着你不需要在测试配置之前或作为测试配置的一部分运行 `collectstatic`。