管理静态文件(例如图像、JavaScript、CSS)

网站通常需要其它文件,例如:图片、JavaScript 或者CSS。 在Django中,我们将这类文件统称为“静态文件”。 Django提供django.contrib.staticfiles来帮助管理它们。

本页面描述如何放置这些静态文件。

配置静态文件

  1. 确认django.contrib.staticfiles包含在INSTALLED_APPS中。

  2. 在settings文件中定义STATIC_URL,例如:

    STATIC_URL = '/static/'
    
  3. 在模板中,可以硬编码URL如/static/my_app/example.jpg,或者最好使用static模板标签通过配置的STATICFILES_STORAGE存储来构建给定相对路径的URL(当你要切换到用于提供静态文件的内容分发网络(CDN)时,这样做会更容易)。

    {% load static %}
    <img src="{% static "my_app/example.jpg" %}" alt="My image"/>
    
  4. 在你的应用中,将静态文件存储在名为static的目录下。 例如my_app/static/my_app/example.jpg

启用静态文件服务

除了这些配置步骤之外,实际中你还需要启用静态文件服务。

在开发过程中,如果你使用django.contrib.staticfiles,当DEBUG 设置成True 时,runserver 会自动启用静态文件服务(参见django.contrib.staticfiles.views.serve())。

这个方法非常低效而且可能不安全,所以它不适合线上环境

关于线上环境保存静态文件的策略,参见部署静态文件

你的项目可能还有一些静态文件不属于任何一个特定的应用。 除了在应用中使用static/目录,你还可以在settings文件中定义一个目录列表(STATICFILES_DIRS),Django会在其中查找静态文件。 像这样:

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
    '/var/www/static/',
]

staticfiles 如何查找静态文件的细节,请参见STATICFILES_FINDERS 设置的文档。

静态文件的命名空间

现在,我们虽然能够将静态文件直接放在my_app/static/之下(不用再创建一个my_app子目录),但是这是一个坏主意。 Django将使用它找到的名称匹配第一个静态文件, 如果你在另外一个不同 的应用中有相同名称的静态文件,Django将无法区分它们。 我们需要让Django 能够找到正确的静态文件,最简单的方法是给它们加上命名空间 方法是将这些静态文件放在与应用同名的另外一个目录中。

开发过程中静态文件的放置

如上所述,如果你启用django.contrib.staticfiles,当DEBUG 设置为True 时,runserver 将自动启用静态文件服务。 如果在INSTALLED_APPS中没有django.contrib.staticfiles,你仍然可以使用django.views.static.serve()视图手工启动静态文件服务。

这不适合在线上环境中使用! 关于一些常见的部署策略,参见部署静态文件

例如,如果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)

这个辅助函数只在debug 模式下工作,而且给定的前缀必须是本地的(例如,/static/)而不能是一个URL(例如,http://static.example.com/)。

此辅助函数仅用于实际的STATIC_ROOT文件夹;它不能像django.contrib.staticfiles一样执行静态文件查找。

在开发过程中用户上传文件的放置

在开发期间,可以使用django.views.static.serve()视图在MEDIA_ROOT放置用户上传的媒体文件。

这不适合在线上环境中使用! 关于一些常见的部署策略,参见部署静态文件

例如,如果将MEDIA_URL设置为/media/, 可将下列代码片段添加到urls.py中实现:

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)

该辅助函数仅在debug模式下工作,而且仅当给定的前缀是本地目录 (例如 /media/)而不能是一个URL (例如http://media.example.com/)..

测试

当使用真正的HTTP请求而不是内建的测试客户端的时候(例如使用内建的LiveServerTestCase) ,静态内容需要和其它内容同时位于服务器上,这样测试环境尽可能的和生产环境相同,但是LiveServerTestCase只有最基本的静态文件服务功能:它不了解staticfiles的查找功能并且认为所有静态内容都被收集在STATIC_ROOT下。

因此,staticfiles带有自己的django.contrib.staticfiles.testing.StaticLiveServerTestCase,这是一个内置子类,在这些测试执行期间具有透明地服务所有内容的能力,方式非常类似于在开发时使用DEBUG = True,即不必先使用collectstatic来收集它们。

部署

django.contrib.staticfiles 提供一个便捷的管理命令用于将静态文件收集到一个目录中,这样你就可以轻松地供给这些文件

  1. STATIC_ROOT设置为你提供文件的目录,例子如下

    STATIC_ROOT = "/var/www/example.com/static/"
    
  2. 运行collectstatic管理命令

    $ python manage.py collectstatic
    

    这会将所有你在所有static目录下的所有的文件都复制到 STATIC_ROOT 目录中

  3. 使用你所选择的Web服务器来服务这些文件。 部署静态文件讲了一些常见的静态文件部署策略。

了解更多

此文档覆盖基本的和常见的使用模式。 关于django.contrib.staticfiles所包含的完整设置、命令、模板标签、以及其它内容, 见静态文件参考