You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python Django如何为Article模型ImageField生成同目录下的_thumb后缀缩略图

实现方案

首先确保已安装图片处理依赖Pillow:

pip install pillow

方法一:重写模型save方法(最简单直接)

直接修改Article模型的save方法,在原图片保存完成后自动生成缩略图,代码如下:

import os
from PIL import Image
from django.db import models
from django.urls import reverse

class Article(models.Model):
    title = models.CharField(max_length=200, verbose_name='Name',)
    photo = models.ImageField(upload_to='news/%Y/%m/%d/', blank=True, 
    verbose_name='Image')

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('article', kwargs={'art_id': self.id})

    def save(self, *args, **kwargs):
        # 先执行原保存逻辑,确保原图片已上传存储
        super().save(*args, **kwargs)
        
        # 只有当photo字段有内容时才处理缩略图
        if self.photo:
            # 解析原图片的路径和文件名
            img_path = self.photo.path
            img_dir = os.path.dirname(img_path)
            img_fullname = os.path.basename(img_path)
            img_name, _ = os.path.splitext(img_fullname)
            
            # 生成缩略图的存储路径
            thumb_path = os.path.join(img_dir, f"{img_name}_thumb.jpg")
            
            # 打开原图片并处理
            with Image.open(img_path) as img:
                # 可自定义缩略图最大尺寸,示例为宽高最大300px
                max_size = (300, 300)
                # 保持原图比例缩放
                img.thumbnail(max_size)
                
                # 处理RGBA、P格式转JPG的透明通道兼容问题
                if img.mode in ("RGBA", "P"):
                    img = img.convert("RGB")
                
                # 保存为JPG格式,质量可在0-100区间自定义
                img.save(thumb_path, "JPEG", quality=85)

方法二:使用Django信号(适合多模型复用场景)

如果多个模型都需要生成缩略图,可以用post_save信号实现逻辑解耦:

  1. 首先在应用目录下新建signals.py,写入以下代码:
import os
from PIL import Image
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Article

@receiver(post_save, sender=Article)
def generate_thumbnail(sender, instance, created, **kwargs):
    if not instance.photo:
        return
    
    # 路径解析、图片处理逻辑和save方法中的实现完全一致
    img_path = instance.photo.path
    img_dir = os.path.dirname(img_path)
    img_fullname = os.path.basename(img_path)
    img_name, _ = os.path.splitext(img_fullname)
    thumb_path = os.path.join(img_dir, f"{img_name}_thumb.jpg")
    
    with Image.open(img_path) as img:
        max_size = (300, 300)
        img.thumbnail(max_size)
        if img.mode in ("RGBA", "P"):
            img = img.convert("RGB")
        img.save(thumb_path, "JPEG", quality=85)
  1. 再到应用的apps.py中注册信号:
from django.apps import AppConfig

class YourAppConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = '替换为你的应用名称'

    def ready(self):
        import 替换为你的应用名称.signals

注意事项

  • 可根据业务需求调整max_size参数自定义缩略图尺寸,调整quality参数平衡缩略图清晰度和文件大小
  • 如果需要删除文章时同步删除对应缩略图,可新增pre_delete信号,逻辑和生成逻辑类似,找到对应路径删除文件即可
  • 如果使用第三方云存储(如OSS、S3),需要将本地路径读写逻辑替换为对应存储服务的文件操作接口

内容的提问来源于stack exchange,提问作者AeroFlow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 03:00:01