当前位置: 首页 > article >正文

vue3 + element-plus 的 upload + axios + django 文件上传并保存

之前在网上搜了好多教程,一直没有找到合适自己的,要么只有前端部分没有后端,要么就是写的不是很明白。所以还得靠自己摸索出来后,来此记录一下整个过程。

  • 其实就是不要用默认的 action,要手动实现上传方式 http-request,然后再传给后端进行各种操作了
    • 这里隐藏了文件展示列表
    • 展示了上传文件的个数
    • 文件去重上传
    • 也对上传文件的格式做了限制
    • 在点击创建的时候 progress 会随着上传进度动态变化

环境安装什么的就不讲了,直接上代码好吧,这个是样式图

这是vue3代码

<template>
  <el-upload class="upload-demo form-item" v-model:file-list="fileList" drag multiple :http-request="httpRequest" :show-file-list="false" auto-upload="false" :accept=upload_accept>
      <el-icon class="el-icon--upload"><upload-filled /></el-icon>
      <div class="el-upload__text">拖拽 / 点击上传文件 ( zip, jpg, png ……)</div>
      <template #tip>
          <div class="el-upload__tip">已上传 {{ fileListLength }} 个文件</div>
      </template>
  </el-upload>
  <el-progress :percentage="progress.curr" :color="progress.color" />
  <el-button type="info" class="btn" @click="removeFile">清空文件</el-button>
  <el-button type="primary" class="btn" @click="create">创建</el-button>
</template>

<script setup lang="ts">
import { ref, watch } from "vue";
import http from "@/utils/axios/index";
import { UploadFilled } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';


const public_elmsg_success = (msg: string) => {
  ElMessage({ type: 'success', duration: 1000, showClose: true, message: msg })
};

const public_elmsg_warning = (msg: string) => {
  ElMessage({ type: 'warning', duration: 1000, showClose: true, message: msg })
};

const public_elmsg_error = (msg: string) => {
  ElMessage({ type: 'error', duration: 1000, showClose: true, message: msg })
};

const upload_accept = ref(".JPG,.PNG,.JPEG,.PCD,.MP4,.AVI,.DAT,.DVR,.VCD,.MOV,.SVCD,.VOB,.DVD,.DVTR,.DVR,.BBC,.EVD,.FLV,.RMVB,.WMV,.MKV,.3GP,.ZIP"); // 限制了上传文件的格式 大写后缀
const upload_lower = ref(upload_accept.value.split(',').map((item: any) => item.toLowerCase())); // 限制上传文件的格式 小写后缀
const fileList: any = ref([]);
const fileList1: any = ref([]);
const fileListLength = ref(0);

const progress = ref({ "curr": 0, "color": "orange" })


watch(fileList1, (newVal, oldVal) => {
  console.log(newVal, oldVal)
  fileListLength.value = newVal.value;
  fileListLength.value = newVal.length;
}, { immediate: true, deep: true });

const httpRequest = (options: any) => {
  let nameList: Array<any> = [];
  fileList1.value.forEach((item: any) => {
      nameList.push(item.name);
  });
  const file_suffix = options.file.name.split(".");
  if (!upload_lower.value.includes(`.${file_suffix[file_suffix.length - 1]}`)) {
      public_elmsg_warning(`文件 ${options.file.name} 格式不正确`);
      return;
  }
  if (nameList.includes(options.file.name)) { }
  else {
      fileList1.value.push(options.file)
  }
  fileList.value = fileList1.value;
}

const removeFile = () => {
  fileList.value = [];
  fileList1.value = [];
  progress.value.curr = 0;
}


const create = () => {
  const formData = new FormData()
  fileList1.value.forEach((file: any) => {
      console.log(file)
      formData.append('files', file)
  })

  http.post("task/create/", formData, {
      headers: { "Content-Type": "multipart/form-data" }, onUploadProgress(progressEvent: any) {
          progress.value.curr = Math.round((progressEvent.loaded * 100) / progressEvent.total)
          if (progress.value.curr == 100) { progress.value.color = 'green' }
          else { progress.value.color = 'orange' }
      },
  }).then((res: any) => {
      if (res.code == 0) {
          public_elmsg_success("任务创建成功")
      }
      else { public_elmsg_error(res.msg) }
  }
  );
}
</script>

v3版本的 djagno 代码

from loguru import logger
from django.http.response import JsonResponse
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
    def create_task(request):
        files = request.FILES.getlist('files')
        for fit in files:
        logger.info(f"name: {fit.name} size: {round(fit.size/ 1024 / 1024 / 1024, 5)} G")
        # 保存文件
        #  with open(f"{os.sep.join(['.', fit['name']])}", mode="wb") as f:
        #         f.write(fit)

        return JsonResponse({"code": 0, "msg": "success"})

http://www.kler.cn/a/386829.html

相关文章:

  • Android SystemUI——CarSystemBar添加到窗口(十)
  • 嵌入式硬件篇---基本组合逻辑电路
  • ChatGPT 写作系列
  • OA-CNN:用于 3D 语义分割的全自适应稀疏 CNN
  • Docker安装PostGreSQL docker安装PostGreSQL 完整详细教程
  • 讲一下ZooKeeper的持久化机制?
  • Spark中的shuffle过程详细
  • 使用AutoMySQLBackup 数据库自动备份
  • 【LeetCode】【算法】146. LRU缓存
  • CSP/信奥赛C++刷题训练:经典信奥数学例题(3):洛谷P1075 :[NOIP2012 普及组] 质因数分解
  • JAVA_冒泡排序
  • 数字身份发展趋势前瞻:身份韧性与安全
  • c语言其实很简单----【数组】
  • Spring WebFlux 核心原理(2-3)
  • Nginx简易配置将内网网站ssh转发到外网
  • 【计网不挂科】计算机网络期末考试(综合)——【选择题&填空题&判断题&简述题】完整题库
  • ArcGIS Pro SDK (二十二)订阅和搜索
  • 算法【Java】—— 动态规划之路径问题
  • 在 PostgreSQL 中,重建索引可以通过 `REINDEX` 命令来完成
  • 特殊符号大全
  • 工作:三菱PLC R系列的程序、子程序及中断程序
  • 电子取证小白教程
  • Python OpenCV形态学处理和图像梯度
  • nuiapp vue3 uni-ui uni.uploadFile 图片上传
  • I.MX6U 裸机开发5.准备C环境并用C语言控制LED
  • 数据血缘追踪是如何在ETL过程中发挥作用?