如何在Django项目中使用Dropzone.js实现多文件上传功能
问题根因
当前Dropzone默认对每个选中的文件单独发起一次POST请求,每一次请求都会触发后端Ajax_file_uploads视图执行一次Post实例保存逻辑,因此上传多少个文件就会生成多少条Post记录和对应的附件记录,和预期不符。
解决方案
方案一:合并所有文件到单次请求(最简单,适配现有后端逻辑)
无需修改后端代码,仅调整Dropzone配置即可,开启多文件合并上传后,所有选中的文件会和表单字段放在同一个POST请求里提交,后端只会生成1条Post记录,所有附件关联到该Post。
修改Dropzone初始化的关键配置如下:
var myDropzone = new Dropzone(id, { // 其他原有配置保持不变 uploadMultiple: true, // 开启多文件合并上传,把原注释的这行打开设为true parallelUploads: 5, // 和maxFiles配置保持一致即可 paramName: "file", // 和后端接收的文件字段名保持一致,默认是file可以省略 // 其他原有配置保持不变 });
方案二:先创建Post再上传附件(适合大文件上传、需要单独处理每个文件的场景)
如果业务需要单独处理每个文件(比如单独的上传进度、失败重传),可以拆分业务逻辑:先提交文章表单创建Post实例,拿到Post ID后再上传附件,后端直接用ID关联附件,避免重复创建Post。
后端修改
# 新增附件单独上传视图 def upload_attach(request): if request.method == "POST": post_id = request.POST.get("post_id") # 增加权限校验,避免越权操作其他用户的文章 post = Post.objects.get(id=post_id, user=request.user) f = request.FILES.get("file") FileAttach.objects.create(file=f, post=post) return JsonResponse({"error": False, "message": "上传成功"}) # 原有提交文章的视图修改,仅保存Post不处理文件 def submit_post(request): if request.method == "POST": p_form = PostForm(request.POST or None) if p_form.is_valid(): art = p_form.save(commit=False) art.user = request.user art.save() return JsonResponse({"error": False, "post_id": art.id}) else: return JsonResponse({"error": True, "errors": p_form.errors})
前端修改
调整表单提交逻辑,先提交文章拿到Post ID再触发文件上传:
init: function () { $("#form-data").validate({ submitHandler: function (form) { // 先提交文章表单 $.post('/submit/post/', $(form).serialize(), function(res){ if(!res.error){ // 把返回的Post ID加到每个文件的上传参数中 myDropzone.on("sending", function(file, xhr, formData){ formData.append("post_id", res.post_id); }); // 修改上传地址为单独的附件上传接口 myDropzone.options.url = '/upload/attach/'; // 开始上传所有文件 myDropzone.enqueueFiles(myDropzone.getFilesWithStatus(Dropzone.ADDED)); } }) } }); },
内容的提问来源于stack exchange,提问作者afi
相关产品推荐
相关产品推荐

