如何覆写cleaned_data变量 实现表单上传图片加水印后直接保存
问题原因
你当前的代码逻辑里,手动调用im.save()存储了加水印的图片,但是form.save()执行时会自动把表单上传的原始图片再存储一次,所以才会出现水印版和原图同时存在的情况。
修正后代码
from django.core.files import File import os if request.method == 'POST': form_w = ImageForm(request.POST, request.FILES) if form_w.is_valid(): form = form_w.save(commit=False) cd = form_w.cleaned_data['img'] im = Image.open(cd) width, height = im.size draw = ImageDraw.Draw(im) text = "TEST WATERMARK" font = ImageFont.truetype('arial.ttf', 36) textwidth, textheight = draw.textsize(text, font) margin = 10 x = width - textwidth - margin y = height - textheight - margin draw.text((x, y), text, font=font) # 保存水印图到目标路径 save_path = 'Luki/media/upload_p/{}'.format(cd.name) im.save(save_path) # 核心改动:将form的img字段指向已保存的水印图,避免自动存储原始文件 form.img.name = f'upload_p/{cd.name}' form.save() return redirect('Luki:gallery') else: form = ImageForm() return render(request, 'Luki/upload_img.html', { 'form': form, })
改动说明
- 原有逻辑中form的img字段始终绑定着用户上传的原始文件,调用
form.save()时会触发Django的自动文件存储逻辑,生成原始图片文件 - 修改后直接给
form.img.name赋值为水印图相对于MEDIA_ROOT的存储路径,form保存时只会把路径写入数据库,不会再生成多余的原始图片文件
注意事项
- 确保
Luki/media/upload_p/目录存在且程序有写入权限,避免图片保存失败 - 如果你的项目MEDIA_ROOT配置不是
Luki/media/,需要对应调整保存路径的前缀 - 可根据需求给文件名添加随机后缀,避免同名文件覆盖
内容的提问来源于stack exchange,提问作者Native856
相关产品推荐
相关产品推荐

