首页 |  我的博客 |  查看该博主内容分类 | 

django-drf、el-upload多文件上传常用思路

前言

多文件上传时,在对模型表处理时,既要考虑文件保存的问题,又要考虑字段接收时能让内容顺利通过的问题,多方面的考虑造成问题变得复杂。那有没有相对逻辑简单的方式呢,本篇就是从该问题点进行的改进思考。

底层逻辑

既然问题的产生是由于多项操作相互耦合造成的,所以,我们可以从解耦上入手,将文件保存和目标模型表处理分开,让流程化繁为简。

解决办法

  1. 将模型表设计为多对多关系
# 目标模型表
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')
  1. 前端上传时,先让用户将文件上传到上述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版)?

posted @ 2023-11-21 10:39  Z哎呀  阅读(524)  评论(0)    收藏  举报