Skip to content

第11章:静态文件和媒体文件

11.1 静态文件管理

STATIC_URL配置

静态文件包括CSS、JavaScript、图片等不经常变动的文件。Django提供了完善的静态文件管理机制。

基本配置:

python
# settings.py
import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent

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

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

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

# 静态文件查找器
STATICFILES_FINDERS = [
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]

应用级别的静态文件组织:

myapp/
    static/
        myapp/
            css/
                style.css
                responsive.css
            js/
                main.js
                utils.js
            images/
                logo.png
                favicon.ico

在模板中使用静态文件:

html
{% load static %}

<!DOCTYPE html>
<html>
<head>
    <title>我的网站</title>
    <!-- CSS文件 -->
    <link rel="stylesheet" type="text/css" href="{% static 'myapp/css/style.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'myapp/css/responsive.css' %}">
</head>
<body>
    <!-- 图片 -->
    <img src="{% static 'myapp/images/logo.png' %}" alt="Logo">
    
    <!-- JavaScript文件 -->
    <script src="{% static 'myapp/js/main.js' %}"></script>
</body>
</html>

collectstatic命令

在生产环境中,需要使用collectstatic命令将所有静态文件收集到STATIC_ROOT目录:

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

# 强制收集(覆盖已存在的文件)
python manage.py collectstatic --noinput --clear

# 只收集特定应用的静态文件
python manage.py collectstatic --noinput --verbosity=2

# 显示将要收集的文件但不实际执行
python manage.py collectstatic --dry-run

自定义collectstatic行为:

python
# management/commands/custom_collectstatic.py
from django.contrib.staticfiles.management.commands.collectstatic import Command as CollectStaticCommand
from django.contrib.staticfiles.storage import staticfiles_storage
import os

class Command(CollectStaticCommand):
    def collect(self):
        # 在收集之前执行自定义逻辑
        self.stdout.write("开始收集静态文件...")
        
        # 调用父类方法
        collected = super().collect()
        
        # 在收集之后执行自定义逻辑
        self.stdout.write("静态文件收集完成!")
        
        return collected

CSS/JS文件组织

推荐的静态文件组织结构:

static/
    css/
        base.css
        components/
            buttons.css
            forms.css
            navigation.css
        pages/
            home.css
            blog.css
        vendor/
            bootstrap.min.css
            fontawesome.css
    js/
        base.js
        components/
            modal.js
            dropdown.js
        pages/
            blog.js
        vendor/
            jquery.min.js
            bootstrap.bundle.min.js
    images/
        logos/
            main-logo.png
            favicon.ico
        icons/
            search.svg
            menu.svg
    fonts/
        custom-font.woff2
    scss/
        base.scss
        components/
            _buttons.scss
        main.scss

在Django中处理SCSS文件:

python
# settings.py
# 安装django-sass-processor
# pip install django-sass-processor

INSTALLED_APPS = [
    # ...
    'sass_processor',
]

STATICFILES_FINDERS = [
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
    'sass_processor.finders.CssFinder',
]

SASS_PROCESSOR_ENABLED = True
SASS_PROCESSOR_ROOT = BASE_DIR / 'static'
scss
// static/scss/main.scss
$primary-color: #007bff;
$secondary-color: #6c757d;

@import "components/buttons";
@import "components/forms";

body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
}

.header {
    background-color: $primary-color;
    color: white;
    padding: 1rem;
}

开发vs生产环境

不同环境下的静态文件配置:

python
# settings/base.py
import os
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent.parent

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    BASE_DIR / "static",
]

# settings/development.py
from .base import *

DEBUG = True

# 开发环境下直接从源目录提供静态文件
STATICFILES_DIRS = [
    BASE_DIR / "static",
    BASE_DIR / "assets",
]

# settings/production.py
from .base import *

DEBUG = False

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

# 启用静态文件压缩
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'

# 使用CDN时的配置
# STATIC_URL = 'https://cdn.example.com/static/'

在生产环境中优化静态文件:

python
# settings/production.py
# 静态文件缓存控制
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'

# 压缩静态文件
# 安装django-compressor
# pip install django-compressor

INSTALLED_APPS = [
    # ...
    'compressor',
]

MIDDLEWARE = [
    # ...
    'compressor.middleware.CompressorMiddleware',
]

COMPRESS_ENABLED = True
COMPRESS_OFFLINE = True  # 离线压缩
COMPRESS_CSS_FILTERS = [
    'compressor.filters.css_default.CssAbsoluteFilter',
    'compressor.filters.cssmin.rCSSMinFilter',
]
COMPRESS_JS_FILTERS = [
    'compressor.filters.jsmin.JSMinFilter',
]

模板中的静态文件压缩:

html
{% load static %}
{% load compress %}

<!DOCTYPE html>
<html>
<head>
    <title>我的网站</title>
    
    {% compress css %}
    <link rel="stylesheet" type="text/css" href="{% static 'css/base.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/components/buttons.css' %}">
    <link rel="stylesheet" type="text/x-scss" href="{% static 'scss/main.scss' %}">
    {% endcompress %}
</head>
<body>
    <!-- 页面内容 -->
    
    {% compress js %}
    <script src="{% static 'js/vendor/jquery.min.js' %}"></script>
    <script src="{% static 'js/base.js' %}"></script>
    <script src="{% static 'js/components/modal.js' %}"></script>
    {% endcompress %}
</body>
</html>

通过这些配置,你可以有效地管理Django项目中的静态文件,确保在开发和生产环境中都能正确提供静态资源。

小结

Django静态文件管理提供了完整的解决方案:

  1. ✅ STATIC_URL配置定义静态文件访问路径
  2. ✅ collectstatic命令收集所有静态资源
  3. ✅ 合理的文件组织结构提升维护性
  4. ✅ 开发和生产环境的差异化配置
  5. ✅ 静态文件压缩优化性能

正确的静态文件管理是Web应用性能优化的重要环节。

下一篇

我们将学习媒体文件的处理。

11.2 媒体文件处理 →

目录

返回课程目录

Released under the Apache 2.0 License.