Django 静态文件处理

静态文件简介

静态文件是指不经常更改的文件,如 CSS 样式表、JavaScript 文件、图片、字体等。Django 提供了强大的静态文件处理系统,可以方便地在开发和生产环境中管理这些文件。

什么是静态文件?
  • CSS 样式表文件
  • JavaScript 客户端脚本
  • 图片 PNG, JPG, SVG, GIF 等
  • 字体 Web 字体文件
  • 图标文件和其他媒体资源
静态文件 vs 媒体文件
静态文件 媒体文件
开发者上传 用户上传
版本控制 动态生成
CSS, JS, 图片 用户头像, 文档
STATIC_URL MEDIA_URL

静态文件配置

在 Django 项目中,需要在 settings.py 文件中配置静态文件相关设置。

基本配置

settings.py
# 静态文件 URL 前缀
STATIC_URL = '/static/'

# 开发环境下静态文件目录
STATICFILES_DIRS = [
    BASE_DIR / "static",
    '/var/www/static/',
]

# 生产环境静态文件收集目录
STATIC_ROOT = BASE_DIR / "staticfiles"

# 静态文件查找器
STATICFILES_FINDERS = [
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
设置 描述
STATIC_URL 静态文件访问的 URL 前缀
STATICFILES_DIRS 开发环境静态文件目录列表
STATIC_ROOT 生产环境静态文件收集目录
STATICFILES_FINDERS 静态文件查找器后端
项目结构
myproject/
  myproject/
    settings.py
    urls.py
  static/
    css/
      style.css
    js/
      app.js
    images/
      logo.png
  myapp/
    static/
      myapp/
        style.css

在模板中使用静态文件

在 Django 模板中,需要使用 {% static %} 模板标签来引用静态文件。

加载静态文件标签
base.html
{# 在模板顶部加载 static 标签 #}
{% load static %}

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>我的网站</title>

    {# 引入 CSS 文件 #}
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static 'css/style.css' %}">

    {# 引入应用特定的 CSS #}
    <link rel="stylesheet" href="{% static 'myapp/style.css' %}">
</head>
<body>
    {# 使用静态图片 #}
    <img src="{% static 'images/logo.png' %}" alt="Logo">

    {# 引入 JavaScript 文件 #}
    <script src="{% static 'js/jquery.min.js' %}"></script>
    <script src="{% static 'js/app.js' %}"></script>
</body>
</html>
静态文件查找顺序
1
应用静态目录
myapp/static/myapp/style.css
2
项目静态目录
static/css/style.css
3
STATICFILES_DIRS
其他自定义目录
使用变量引用静态文件
动态静态文件路径
{% load static %}

{# 在视图中传递静态文件路径 #}
{% with image_path='images/products/'|add:product.id|add:'.jpg' %}
    <img src="{% static image_path %}" alt="{{ product.name }}">
{% endwith %}

{# 或者使用上下文变量 #}
<link rel="stylesheet" href="{% static css_file %}">
提示: 使用 {% static %} 标签可以确保在不同环境中(开发/生产)都能正确引用静态文件。

开发环境配置

在开发环境中,Django 的内置开发服务器可以自动提供静态文件服务。

URL 配置
urls.py
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('myapp.urls')),
]

# 开发环境下提供静态文件服务
if settings.DEBUG:
    urlpatterns += static(
        settings.STATIC_URL,
        document_root=settings.STATIC_ROOT
    )
    urlpatterns += static(
        settings.MEDIA_URL,
        document_root=settings.MEDIA_ROOT
    )
运行开发服务器
终端命令
# 运行开发服务器
python manage.py runserver

# 访问静态文件
# http://localhost:8000/static/css/style.css
# http://localhost:8000/static/js/app.js
# http://localhost:8000/static/images/logo.png
注意: 在生产环境中不要使用 Django 的开发服务器提供静态文件服务,性能较差且不安全。

调试静态文件问题

查找静态文件
# 查找静态文件位置
python manage.py findstatic css/style.css

# 查找所有静态文件
python manage.py findstatic --all
常见问题排查
  • 检查 DEBUG = True
  • 确认 STATICFILES_DIRS 配置正确
  • 验证 URL 配置中包含静态文件路由
  • 检查静态文件目录权限

生产环境配置

在生产环境中,需要使用 collectstatic 命令收集静态文件,并使用 Web 服务器或 CDN 提供服务。

收集静态文件

收集静态文件
# 收集所有静态文件到 STATIC_ROOT
python manage.py collectstatic

# 在部署时自动收集
python manage.py collectstatic --noinput

# 清除旧文件后收集
python manage.py collectstatic --clear

# 干运行模式(不实际执行)
python manage.py collectstatic --dry-run
collectstatic 过程:
  1. 清空 STATIC_ROOT 目录(如果使用 --clear
  2. 使用查找器搜索所有静态文件
  3. 复制文件到 STATIC_ROOT
  4. 应用静态文件存储后端处理

Web 服务器配置

Nginx 配置
nginx.conf
server {
    listen 80;
    server_name example.com;

    # 静态文件服务
    location /static/ {
        alias /path/to/your/staticfiles/;
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # 媒体文件服务
    location /media/ {
        alias /path/to/your/media/;
        expires 30d;
    }

    # Django 应用
    location / {
        proxy_pass http://unix:/path/to/your/app.sock;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
Apache 配置
.htaccess 或虚拟主机
Alias /static/ /path/to/your/staticfiles/
<Directory /path/to/your/staticfiles>
    Require all granted
</Directory>

Alias /media/ /path/to/your/media/
<Directory /path/to/your/media>
    Require all granted
</Directory>

# Django WSGI 配置
WSGIScriptAlias / /path/to/your/project/wsgi.py
WSGIPythonHome /path/to/your/venv
WSGIPythonPath /path/to/your/project

<Directory /path/to/your/project>
    <Files wsgi.py>
        Require all granted
    </Files>
</Directory>

高级配置和优化

使用 WhiteNoise

WhiteNoise 允许 Django 应用直接提供静态文件服务,无需单独的 Web 服务器。

安装和配置
# 安装 WhiteNoise
pip install whitenoise
# settings.py
MIDDLEWARE = [
    'whitenoise.middleware.WhiteNoiseMiddleware',
    # ...
]

# 静态文件存储
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
WhiteNoise 优势
  • 简化部署配置
  • 自动 Gzip 压缩
  • 支持缓存头设置
  • 支持 CDN
  • 无需额外 Web 服务器
适用于中小型应用,高流量网站建议使用 CDN + Web 服务器。

使用 CDN

CDN 配置
# settings.py
AWS_ACCESS_KEY_ID = 'your-access-key'
AWS_SECRET_ACCESS_KEY = 'your-secret-key'
AWS_STORAGE_BUCKET_NAME = 'your-bucket-name'
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
}

# 静态文件配置
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/static/'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
django-storages 配置
# 安装 django-storages
pip install django-storages[boto3]
# settings.py
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'

# 或者分别配置静态和媒体文件
STATICFILES_STORAGE = 'myapp.storage_backends.StaticStorage'
DEFAULT_FILE_STORAGE = 'myapp.storage_backends.MediaStorage'

最佳实践

组织静态文件
  • 按类型组织文件(css/, js/, images/)
  • 为应用特定静态文件创建命名空间
  • 使用有意义的文件名
  • 版本控制大型库文件
static/
  css/
    style.css
    bootstrap.min.css
  js/
    app.js
    jquery-3.6.0.min.js
  images/
    logo.png
    icons/
性能优化
  • 启用 Gzip 压缩
  • 设置合适的缓存头
  • 使用 CDN 加速
  • 合并和压缩 CSS/JS 文件
  • 使用图片懒加载
  • 考虑使用 WebP 格式图片
# Nginx 缓存配置
location /static/ {
    expires 1y;
    add_header Cache-Control "public, immutable";
}
安全考虑
  • 不要在生产环境使用 DEBUG = True
  • 定期更新第三方库
  • 验证用户上传的媒体文件
  • 使用 HTTPS 提供服务
  • 设置合适的文件权限
部署检查清单
  • 运行 collectstatic
  • 配置 Web 服务器静态文件路径
  • 设置正确的文件权限
  • 测试静态文件访问
  • 配置 CDN(如果使用)
  • 设置监控和日志