Django3.2发送带附件邮件报MultiValueDictKeyError 'file'错误如何解决
Django 发送带附件邮件MultiValueDictKeyError错误解决方案
错误触发原因
- 视图未区分GET/POST请求:直接访问/sendEmail/路径时默认发起GET请求,此时
request.FILES为空,强行取file键会直接抛出异常 - 多文件上传适配错误:表单中
file字段开启了multiple=True支持多文件上传,视图中直接按单个文件取值逻辑错误 - 缺少表单校验逻辑:未校验表单合法性就直接从请求中取数据,用户未上传文件直接提交表单时也会触发键不存在异常
修复代码
1. views.py 修复后代码
from django.shortcuts import render from .forms import EmailForm from django.core.mail import EmailMessage from django.conf import settings from django.http import HttpResponse # send email def sendMail(request): # GET请求返回空白表单 if request.method == "GET": form = EmailForm() return render(request, "SendEmail.html", {"form": form}) # POST请求先做表单校验 if request.method == "POST": # 传入POST和FILES参数初始化表单 form = EmailForm(request.POST, request.FILES) if form.is_valid(): # 从校验后的cleaned_data中取数据更安全 message = form.cleaned_data["message"] subject = form.cleaned_data["subject"] receivers = form.cleaned_data["email"] email = EmailMessage(subject, message, settings.EMAIL_HOST_USER, [receivers]) email.content_subtype = "html" # 适配多文件上传,用getlist取所有上传的文件 files = request.FILES.getlist("file") for file in files: email.attach(file.name, file.read(), file.content_type) email.send() return HttpResponse(f"已发送至 {receivers}") # 表单校验失败返回页面,自动携带错误提示 else: return render(request, "SendEmail.html", {"form": form})
2. urls.py 可选优化
如果需要支持带斜杠的访问路径/sendEmail/,可以调整路由配置:
urlpatterns = [ path('sendEmail/', sendMail, name='send-email'), ]
其他注意事项
- 表单默认
file字段为必填项,用户未上传文件提交时会自动触发表单校验错误,不会走到发送逻辑 - 模板中已经正确配置了
enctype="multipart/form-data",不需要调整
内容的提问来源于stack exchange,提问作者Yusuf Berkay GIRGIN
相关产品推荐
相关产品推荐

