---
title: "如何管理静态文件（如图片、JavaScript、CSS）"
version: 5.1
locale: zh-hans
source: https://docs.djangoproject.com/zh-hans/5.1/howto/static-files/
canonical: https://djangodocs.dev/zh-hans/5.1/howto/static-files/
---
# 如何管理静态文件（如图片、JavaScript、CSS）

网站通常需要提供类似图片，JavaScript 或 CSS 的额外文件服务。在 Django 中，我们将这些文件称为“静态文件”。Django 提供了 [`django.contrib.staticfiles`](/zh-hans/5.1/ref/contrib/staticfiles/#module-django.contrib.staticfiles) 帮你管理它们。

本页介绍如何为这些静态文件提供服务。

## 配置静态文件

1. 确保 [`INSTALLED_APPS`](/zh-hans/5.1/ref/settings/#std-setting-INSTALLED_APPS) 包含了 `django.contrib.staticfiles`。
2. 在配置文件中，定义 [`STATIC_URL`](/zh-hans/5.1/ref/settings/#std-setting-STATIC_URL)，例子:

   ```
   STATIC_URL = "static/"
   ```
3. 在模板中，可以使用 [`static`](/zh-hans/5.1/ref/templates/builtins/#std-templatetag-static) 模板标签来使用配置的 `staticfiles` [`STORAGES`](/zh-hans/5.1/ref/settings/#std-setting-STORAGES) 别名构建给定相对路径的 URL。

   ```html+django
   {% load static %}
   <img src="{% static 'my_app/example.jpg' %}" alt="My image">
   ```
4. 将你的静态文件保存至程序中名为 `static` 的目录中。例如 `my_app/static/my_app/example.jpg`。

> **为这些文件提供服务**
>
> 除了这些配置步骤外，你还需要实际地为这些文件提供服务。
>
> 开发时，使用 [`django.contrib.staticfiles`](/zh-hans/5.1/ref/contrib/staticfiles/#module-django.contrib.staticfiles)，这一般会在 [`DEBUG`](/zh-hans/5.1/ref/settings/#std-setting-DEBUG) is set to `True` 情况下由 [`runserver`](/zh-hans/5.1/ref/django-admin/#django-admin-runserver) 自动完成（参考 [`django.contrib.staticfiles.views.serve()`](/zh-hans/5.1/ref/contrib/staticfiles/#django.contrib.staticfiles.views.serve)）。
>
> 该方法 **极度低效** 且 **不怎么安全**，所以这 **不适合生产环境**。
>
> 参考 [如何部署静态文件](/zh-hans/5.1/howto/static-files/deployment/) 了解如何正确地在生产环境提供静态文件服务的策略。

你的工程可能包含未与任何应用绑定的静态资源。除了在 apps 中使用 `static/` 目录，你可以在配置文件中定义一个目录列表 ([`STATICFILES_DIRS`](/zh-hans/5.1/ref/settings/#std-setting-STATICFILES_DIRS)) ，Django 会从中寻找静态文件。例子:

```
STATICFILES_DIRS = [
    BASE_DIR / "static",
    "/var/www/static/",
]
```

参考 [`STATICFILES_FINDERS`](/zh-hans/5.1/ref/settings/#std-setting-STATICFILES_FINDERS) 配置的文档了解 `staticfiles` 是如何找到你的文件的细节。

> **静态文件命名空间**
>
> 现在，我们 *也许* 能直接将静态文件放入 `my_app/static/` 目录（而不是创建另一个 `my_app` 子目录），不过这实际上是个坏主意。Django 会使用第一个名字匹配的静态文件，若你在 *不同的* 应用程序中有一个同名静态文件，Django 无力区分它们。我们需要为 Django 指出正确的那个，而最好的方式就是使用 *命名空间*。也就是说，将这些静态文件放在 *另一个* 以应用程序名本身命名的目录下。
>
> 你可以通过指定 [prefixes](/zh-hans/5.1/ref/settings/#staticfiles-dirs-prefixes) 在 [`STATICFILES_DIRS`](/zh-hans/5.1/ref/settings/#std-setting-STATICFILES_DIRS) 中为静态资源做命名。

## 开发时提供静态文件服务

若你使用了前文所述的 [`django.contrib.staticfiles`](/zh-hans/5.1/ref/contrib/staticfiles/#module-django.contrib.staticfiles)， [`runserver`](/zh-hans/5.1/ref/django-admin/#django-admin-runserver) 会在 [`DEBUG`](/zh-hans/5.1/ref/settings/#std-setting-DEBUG) 为 `True` 时自动处理。若你未在 [`INSTALLED_APPS`](/zh-hans/5.1/ref/settings/#std-setting-INSTALLED_APPS) 中包含 `django.contrib.staticfiles`，你仍能手动通过 [`django.views.static.serve()`](/zh-hans/5.1/ref/views/#django.views.static.serve) 为静态文件提供服务。

这不适合生产环境！常见的部署策略请参考 [如何部署静态文件](/zh-hans/5.1/howto/static-files/deployment/)。

例如，如果你的 [`STATIC_URL`](/zh-hans/5.1/ref/settings/#std-setting-STATIC_URL) 定义为 `static/`，你可以通过将以下片段添加到你的 `urls.py` 中来实现：

```
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
```

> **Note**
>
> 这个帮助函数只在调试模式下工作，而且只在给定的前缀是本地的（例如 `static/`），而不是一个 URL（例如 `http://static.example.com/` ）时才有效。
>
> 当然，助手函数只为实际的 [`STATIC_ROOT`](/zh-hans/5.1/ref/settings/#std-setting-STATIC_ROOT) 目录提供服务；它不会像 [`django.contrib.staticfiles`](/zh-hans/5.1/ref/contrib/staticfiles/#module-django.contrib.staticfiles) 一样搜索静态文件。
>
> 最后，静态文件通过 WSGI 应用程序层的包装器提供服务。因此，静态文件请求不会经过正常的 [中间件链](/zh-hans/5.1/topics/http/middleware/)。

## 开发期间保存用户上传的文件

在开发过程中，你可以使用 [`django.views.static.serve()`](/zh-hans/5.1/ref/views/#django.views.static.serve) 视图从 [`MEDIA_ROOT`](/zh-hans/5.1/ref/settings/#std-setting-MEDIA_ROOT) 为用户上传的媒体文件提供服务。

这不适合生产环境！常见的部署策略请参考 [如何部署静态文件](/zh-hans/5.1/howto/static-files/deployment/)。

例如，如果你的 [`MEDIA_URL`](/zh-hans/5.1/ref/settings/#std-setting-MEDIA_URL) 定义为 `media/`，你可以通过将以下片段添加到你的 [`ROOT_URLCONF`](/zh-hans/5.1/ref/settings/#std-setting-ROOT_URLCONF) 中来实现：

```
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    # ... the rest of your URLconf goes here ...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
```

> **Note**
>
> 这个帮助函数只在调试模式下工作，而且只在给定的前缀是本地的（例如 `media/`），而不是一个URL（例如 `http://media.example.com/` ）时才有效。

## 测试

运行使用真实 HTTP 请求（而不是内置的测试客户端，即内置的 [`LiveServerTestCase`](/zh-hans/5.1/topics/testing/tools/#django.test.LiveServerTestCase)）的测试用例时，静态资源要与剩余内容分别提供服务，这样，测试环境才能尽量重现真实的问题。但 `LiveServerTestCase` 只拥有非常基本的为静态文件提供服务的能力：它并不知道 `staticfiles` 应用的查找功能，且总是假设静态内容已被收集至 [`STATIC_ROOT`](/zh-hans/5.1/ref/settings/#std-setting-STATIC_ROOT) 目录下。

因此， `staticfiles` 自带了 [`django.contrib.staticfiles.testing.StaticLiveServerTestCase`](/zh-hans/5.1/ref/contrib/staticfiles/#django.contrib.staticfiles.testing.StaticLiveServerTestCase)，这是一个内置子类，能够透明地以类似我们在开发阶段 `DEBUG = True` 时获得的方式为所有静态资源在测试期间提供服务。即无需先用 [`collectstatic`](/zh-hans/5.1/ref/contrib/staticfiles/#django-admin-collectstatic) 收集它们。

## 部署

[`django.contrib.staticfiles`](/zh-hans/5.1/ref/contrib/staticfiles/#module-django.contrib.staticfiles) 提供了一个便利的管理命令，用于将静态文件收集至独立目录，方便你为它们提供服务。

1. 将 [`STATIC_ROOT`](/zh-hans/5.1/ref/settings/#std-setting-STATIC_ROOT) 配置成你喜欢的目录，在这个目录提供服务，例如:

   ```
   STATIC_ROOT = "/var/www/example.com/static/"
   ```
2. 运行 [`collectstatic`](/zh-hans/5.1/ref/contrib/staticfiles/#django-admin-collectstatic) 管理命令：

   ```shell
   $ python manage.py collectstatic
   ```

   这将会把静态目录下的所有文件拷贝至 [`STATIC_ROOT`](/zh-hans/5.1/ref/settings/#std-setting-STATIC_ROOT) 目录。
3. 选一个 Web 服务器为这些文件提供服务。 文档 [如何部署静态文件](/zh-hans/5.1/howto/static-files/deployment/) 介绍了静态文件的常见部署策略。

## 了解更多

本文档已覆盖基础和常见模式。对于所有配置项，命令，模板标签和其他包含在 [`django.contrib.staticfiles`](/zh-hans/5.1/ref/contrib/staticfiles/#module-django.contrib.staticfiles) 碎片的全部细节，参考 [静态文件参考](/zh-hans/5.1/ref/contrib/staticfiles/)。
