每天40分玩转Django:Django静态文件
Django静态文件
一、今日学习内容概述
学习模块 | 重要程度 | 主要内容 |
---|---|---|
静态文件配置 | ⭐⭐⭐⭐⭐ | 基础设置、路径配置 |
CDN集成 | ⭐⭐⭐⭐⭐ | CDN配置、资源优化 |
静态文件处理 | ⭐⭐⭐⭐ | 压缩、版本控制 |
部署优化 | ⭐⭐⭐⭐ | 性能优化、缓存策略 |
二、基础配置
# settings.py
import os
# 静态文件配置
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]
# 静态文件查找器
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
# CDN 配置
CDN_DOMAIN = 'https://cdn.example.com'
USE_CDN = True
# 压缩配置
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
三、项目结构示例
myproject/
├── manage.py
├── myproject/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── static/
│ ├── css/
│ │ ├── main.css
│ │ └── vendor/
│ ├── js/
│ │ ├── main.js
│ │ └── vendor/
│ └── images/
└── templates/
├── base.html
└── includes/
四、静态文件管理器
# storage.py
from django.contrib.staticfiles.storage import StaticFilesStorage
from django.conf import settings
import os
import hashlib
class CustomStaticStorage(StaticFilesStorage):
"""自定义静态文件存储"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.prefix = settings.STATIC_URL.rstrip('/')
def url(self, name):
"""生成文件URL"""
url = super().url(name)
if settings.USE_CDN:
return f"{settings.CDN_DOMAIN}{url}"
return url
def hashed_name(self, name, content=None, filename=None):
"""生成带哈希值的文件名"""
if content is None:
return name
md5 = hashlib.md5()
for chunk in content.chunks():
md5.update(chunk)
hash_value = md5.hexdigest()[:12]
name_parts = name.split('.')
name_parts.insert(-1, hash_value)
return '.'.join(name_parts)
五、模板使用示例
<!-- templates/base.html -->
{% load static %}
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
<!-- CSS 文件 -->
<link rel="stylesheet" href="{% static 'css/vendor/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'css/main.css' %}">
<!-- 自定义CDN引用 -->
{% if settings.USE_CDN %}
<link rel="preconnect" href="{{ settings.CDN_DOMAIN }}">
{% endif %}
</head>
<body>
<nav class="navbar">
<img src="{% static 'images/logo.png' %}" alt="Logo">
<!-- 导航内容 -->
</nav>
<main>
{% block content %}{% endblock %}
</main>
<!-- JavaScript 文件 -->
<script src="{% static 'js/vendor/jquery.min.js' %}"></script>
<script src="{% static 'js/vendor/bootstrap.bundle.min.js' %}"></script>
<script src="{% static 'js/main.js' %}"></script>
</body>
</html>
六、静态文件处理流程图
七、CDN配置和优化
# cdn.py
from django.core.files.storage import get_storage_class
from django.conf import settings
import requests
class CDNStorage:
"""CDN存储管理器"""
def __init__(self):
self.storage = get_storage_class()()
self.cdn_domain = settings.CDN_DOMAIN
def sync_file(self, path):
"""同步文件到CDN"""
try:
with self.storage.open(path) as f:
response = requests.put(
f"{self.cdn_domain}/{path}",
data=f.read(),
headers={
'Content-Type': self.storage.mime_type(path),
'Cache-Control': 'public, max-age=31536000'
}
)
return response.status_code == 200
except Exception as e:
print(f"CDN同步失败: {str(e)}")
return False
def purge_file(self, path):
"""清除CDN缓存"""
try:
response = requests.delete(
f"{self.cdn_domain}/purge/{path}",
headers={'Authorization': f'Bearer {settings.CDN_API_KEY}'}
)
return response.status_code == 200
except Exception as e:
print(f"缓存清除失败: {str(e)}")
return False
八、静态文件压缩
# compressor.py
from django.contrib.staticfiles.storage import CompressedManifestStaticFilesStorage
import subprocess
class CustomCompressedStorage(CompressedManifestStaticFilesStorage):
"""自定义压缩存储"""
def post_process(self, paths, dry_run=False, **options):
"""处理文件后进行压缩"""
for path in paths:
if path.endswith(('.css', '.js')):
full_path = self.path(path)
# CSS压缩
if path.endswith('.css'):
subprocess.run(['cleancss', '-o', full_path, full_path])
# JS压缩
if path.endswith('.js'):
subprocess.run(['uglifyjs', full_path, '-o', full_path])
return super().post_process(paths, dry_run, **options)
# 压缩命令
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = '压缩静态文件'
def handle(self, *args, **options):
storage = CustomCompressedStorage()
storage.collect()
九、性能优化建议
- 文件合并
# utils.py
def combine_files(file_list, output_path):
"""合并多个文件"""
with open(output_path, 'wb') as output:
for file_path in file_list:
with open(file_path, 'rb') as input_file:
output.write(input_file.read())
output.write(b'\n')
- 缓存配置
# settings.py
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}
# 静态文件缓存设置
STATICFILES_CACHE_TIMEOUT = 60 * 60 * 24 * 30 # 30天
- 图片优化
# image_optimizer.py
from PIL import Image
import os
def optimize_image(input_path, output_path=None, quality=85):
"""优化图片质量和大小"""
if output_path is None:
output_path = input_path
with Image.open(input_path) as img:
# 保存优化后的图片
img.save(
output_path,
quality=quality,
optimize=True
)
- 版本控制
# context_processors.py
from django.conf import settings
def static_version(request):
"""添加静态文件版本号"""
return {
'STATIC_VERSION': getattr(settings, 'STATIC_VERSION', '1.0.0')
}
十、部署注意事项
- 收集静态文件
python manage.py collectstatic --noinput
- Nginx配置
# 静态文件服务
location /static/ {
alias /path/to/staticfiles/;
expires 30d;
add_header Cache-Control "public, no-transform";
}
- 监控和日志
# middleware.py
class StaticFileMonitorMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
if request.path.startswith(settings.STATIC_URL):
# 记录静态文件访问
logger.info(f"Static file accessed: {request.path}")
return self.get_response(request)
通过本章学习,你应该能够:
- 配置Django静态文件系统
- 集成和使用CDN
- 实现静态文件优化
- 管理文件版本和缓存
怎么样今天的内容还满意吗?再次感谢朋友们的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!