Django 2.0多文件上传问题:仅保留最后一个文件的技术问询
解决Django 2.0多文件上传仅保留最后一个的问题
看起来你踩了多文件上传的常见坑——直接操作上传的文件对象而没有为每个文件创建对应的模型实例,而且表单也没配置成支持多文件选择。我来一步步帮你搞定:
1. 先修正表单配置,支持多文件选择
首先你的表单需要明确允许选择多个文件,修改forms.py里的表单类:
from django import forms from .models import Resource # 假设你的模型叫Resource class ResourceForm(forms.ModelForm): # 重定义文件字段,添加multiple属性让浏览器支持多选文件 Resource_file = forms.FileField( widget=forms.ClearableFileInput(attrs={'multiple': True}) ) class Meta: model = Resource fields = ['Resource_file']
2. 修正CBV的post方法,为每个文件创建模型实例
你之前的代码里直接调用f.save()是错误的,因为f是InMemoryUploadedFile对象,不是你的模型实例。正确的做法是循环每个上传的文件,为每个文件创建一个新的Resource实例并保存:
def post(self, request, *args, **kwargs): form_class = self.get_form_class() form = self.get_form(form_class) files = request.FILES.getlist('Resource_file') if form.is_valid(): # 不要直接调用form.save(),它只会创建一个关联最后一个文件的实例 for file in files: # 为每个文件创建新的模型实例 resource_instance = Resource(Resource_file=file) # 如果你的模型有其他字段(比如标题、描述),可以从form的cleaned_data里取值 # resource_instance.title = form.cleaned_data.get('title') resource_instance.save() # 这里可以返回成功页面的重定向,或者复用form_valid的逻辑 return self.form_valid(form) else: return self.form_invalid(form)
3. 别忘了模板里的表单属性
你的HTML表单必须加上enctype="multipart/form-data",否则文件根本传不上去:
<form method="POST" enctype="multipart/form-data"> {% csrf_token %} {{ form.as_p }} <button type="submit">上传文件</button> </form>
额外说明:如果想在单个模型实例里存多个文件
如果你的需求是一个父实例关联多个文件(比如一篇文章对应多个附件),那你需要调整模型结构:
# models.py class Resource(models.Model): title = models.CharField(max_length=100) # 其他父级字段 class ResourceAttachment(models.Model): resource = models.ForeignKey(Resource, on_delete=models.CASCADE, related_name='attachments') file = models.FileField(upload_to='resource_attachments/')
然后在post方法里,先保存父实例,再循环创建附件实例:
def post(self, request, *args, **kwargs): form_class = self.get_form_class() form = self.get_form(form_class) files = request.FILES.getlist('attachments') if form.is_valid(): # 先保存父实例 resource_instance = form.save() # 为每个文件创建附件实例 for file in files: ResourceAttachment.objects.create(resource=resource_instance, file=file) return self.form_valid(form) else: return self.form_invalid(form)
这样就能完美实现多文件上传并保留所有文件啦!
内容的提问来源于stack exchange,提问作者Loki
相关产品推荐
相关产品推荐

