django-drf、el-upload多文件上传常用思路
前言
多文件上传时,在对模型表处理时,既要考虑文件保存的问题,又要考虑字段接收时能让内容顺利通过的问题,多方面的考虑造成问题变得复杂。那有没有相对逻辑简单的方式呢,本篇就是从该问题点进行的改进思考。
底层逻辑
既然问题的产生是由于多项操作相互耦合造成的,所以,我们可以从解耦上入手,将文件保存和目标模型表处理分开,让流程化繁为简。
解决办法
- 将模型表设计为多对多关系
# 目标模型表
class TargetTable(models.Model):
...
files = models.ManyToManyField(verbose_name='附件', to='FilesTable', on_delete=models.PROTECT)
...
# 存储文件的表
class FilesTable(models.Model):
name = models.CharField(verbose_name='名称', max_length=255)
file = models.FileField(verbose_name='文件', upload_to='data/uploads')
- 前端上传时,先让用户将文件上传到上述FilesTable模型表,然后后端返回所有已上传的文件,通过选择框的方式获取选取文件的id,后端存储这些id到TargetTable目标表files字段即可(多对多set(ids))。如:
- 上传附件界面

- 附件选择界面

代码参考:
<!-- 上传附件界面 -->
<el-dialog title="上传附件"
:visible.sync="uploadVisible"
width="30%"
center
>
<el-upload
action=""
:on-change="(file, fileList) => uploadForm.fileList = fileList.map(file => file.raw)"
:on-remove="(file, fileList) => uploadForm.fileList = fileList.map(file => file.raw)"
:auto-upload="false"
multiple
drag
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">请勿上传过大的文件</div>
</el-upload>
</el-dialog>
<!-- 附件选择界面 -->
<el-form-item>
<el-select v-model=""
placeholder="请选择需要上传的附件"
filterable
crearable
multiple
>
<el-option v-for="item in items"
:label="item.name"
:value="item.id"
:key="item.id"
></el-option>
</el-select>
<el-button type="text"
style="margin-left: 10px"
@click="uploadVisible = true"
>上传附件</el-button>
</el-form-item>
后端处理:
- 目标表做一个ModelViewSet视图
- 文件表做一个APIView视图
class TargetView(ModelViewSet):
queryset = models.TargetTable.objects.order_by('-id')
serializer_class = TargetTableSerializer
class FilesTableView(ModelViewSet):
queryset = models.FilesTable.objects.order_by('-id')
def get_serializer_class(self):
return FilesTableSerializer
def create(self, request, *args, **kwargs):
files = request.data.getlist('files[]')
objs = [
models.FilesTable(
file=file
)
for file in files
]
objs = models.FilesTable.objects.bulk_create(objs)
return Ret(return_code.SUCCESS, len(objs))
PS: 文件上传处理方式请参考:el-upload如何灵活使用http-request自定义上传方法(2.0版)?

浙公网安备 33010602011771号