Django存储应用如何返回小尺寸预览图以提升跨项目图片加载速度
Django Drive 应用图片加载速度优化方案
方案一:上传阶段预生成多规格缩略图(推荐)
这是性能最优的方案,避免请求时实时处理图片的资源消耗:
- 首先安装图片处理依赖:
pip install pillow - 扩展File模型,新增不同尺寸的缩略图存储字段,示例模型修改如下:
from django.db import models from PIL import Image import os class File(models.Model): # 原有字段保留 file = models.FileField(upload_to="original/") thumbnail_200 = models.ImageField(upload_to="thumb/200/", null=True, blank=True) thumbnail_800 = models.ImageField(upload_to="thumb/800/", null=True, blank=True) # 其他原有字段... def save(self, *args, **kwargs): super().save(*args, **kwargs) # 生成200px宽度缩略图 if self.file and not self.thumbnail_200: img = Image.open(self.file.path) if img.height > 200 or img.width > 200: output_size = (200, 200) img.thumbnail(output_size) thumb_path = f"thumb/200/{os.path.basename(self.file.path)}" img.save(thumb_path) self.thumbnail_200 = thumb_path super().save(update_fields=["thumbnail_200"]) # 同理生成800px等其他规格缩略图
- 修改serve函数,支持通过请求参数指定返回的图片规格,示例修改:
def serve(request, path, document_root=None): file = File.objects.get(privacy__link=path) # 获取请求的尺寸参数,默认返回800px缩略图 size = request.GET.get("size", "800") if size == "200" and file.thumbnail_200: resp_file = file.thumbnail_200 elif size == "original": resp_file = file.file else: resp_file = file.thumbnail_800 if file.thumbnail_800 else file.file rendered_file = FileResponse(resp_file) # 增加缓存头,降低重复请求消耗 rendered_file["Cache-Control"] = "public, max-age=31536000" return rendered_file
方案二:动态生成缩略图+缓存(适合存量图片多的场景)
如果已经有大量历史上传的图片,不想批量回刷生成缩略图,可以用动态生成+缓存的方案:
- 安装django-imagekit库:
pip install django-imagekit - 在模型中定义动态缩略图规格,请求时自动生成并缓存,无需提前处理
- serve函数中直接返回对应规格的动态缩略图即可,首次请求生成后后续请求直接返回缓存结果,性能接近预生成方案。
方案三:文件服务侧性能优化
即使返回缩略图,Django直接提供文件服务的性能依然远低于专门的静态文件服务,可做如下优化:
- 正式环境不要用Django直接处理静态文件请求,改为Nginx代理静态资源路径,响应速度可以提升数倍
- 增加CDN层缓存所有图片资源,进一步降低源站压力和跨地域访问延迟
内容的提问来源于stack exchange,提问作者Muhammed Atif
相关产品推荐
相关产品推荐

