经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Django » 查看文章
vue3 + element-plus 的 upload + axios + django 文件上传并保存
来源:cnblogs  作者:卫龙吖  时间:2024/1/10 8:57:13  对本文有异议

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

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

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

 

这是vue3代码

  1. 1 <template>
  2. 2 <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>
  3. 3 <el-icon class="el-icon--upload"><upload-filled /></el-icon>
  4. 4 <div class="el-upload__text">拖拽 / 点击上传文件 ( zip, jpg, png ……)</div>
  5. 5 <template #tip>
  6. 6 <div class="el-upload__tip">已上传 {{ fileListLength }} 个文件</div>
  7. 7 </template>
  8. 8 </el-upload>
  9. 9 <el-progress :percentage="progress.curr" :color="progress.color" />
  10. 10 <el-button type="info" class="btn" @click="removeFile">清空文件</el-button>
  11. 11 <el-button type="primary" class="btn" @click="create">创建</el-button>
  12. 12 </template>
  13. 13
  14. 14 <script setup lang="ts">
  15. 15 import { ref, watch } from "vue";
  16. 16 import http from "@/utils/axios/index";
  17. 17 import { UploadFilled } from '@element-plus/icons-vue';
  18. 18 import { ElMessage } from 'element-plus';
  19. 19
  20. 20
  21. 21 const public_elmsg_success = (msg: string) => {
  22. 22 ElMessage({ type: 'success', duration: 1000, showClose: true, message: msg })
  23. 23 };
  24. 24
  25. 25 const public_elmsg_warning = (msg: string) => {
  26. 26 ElMessage({ type: 'warning', duration: 1000, showClose: true, message: msg })
  27. 27 };
  28. 28
  29. 29 const public_elmsg_error = (msg: string) => {
  30. 30 ElMessage({ type: 'error', duration: 1000, showClose: true, message: msg })
  31. 31 };
  32. 32
  33. 33 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"); // 限制了上传文件的格式 大写后缀
  34. 34 const upload_lower = ref(upload_accept.value.split(',').map((item: any) => item.toLowerCase())); // 限制上传文件的格式 小写后缀
  35. 35 const fileList: any = ref([]);
  36. 36 const fileList1: any = ref([]);
  37. 37 const fileListLength = ref(0);
  38. 38
  39. 39 const progress = ref({ "curr": 0, "color": "orange" })
  40. 40
  41. 41
  42. 42 watch(fileList1, (newVal, oldVal) => {
  43. 43 console.log(newVal, oldVal)
  44. 44 fileListLength.value = newVal.value;
  45. 45 fileListLength.value = newVal.length;
  46. 46 }, { immediate: true, deep: true });
  47. 47
  48. 48 const httpRequest = (options: any) => {
  49. 49 let nameList: Array<any> = [];
  50. 50 fileList1.value.forEach((item: any) => {
  51. 51 nameList.push(item.name);
  52. 52 });
  53. 53 const file_suffix = options.file.name.split(".");
  54. 54 if (!upload_lower.value.includes(`.${file_suffix[file_suffix.length - 1]}`)) {
  55. 55 public_elmsg_warning(`文件 ${options.file.name} 格式不正确`);
  56. 56 return;
  57. 57 }
  58. 58 if (nameList.includes(options.file.name)) { }
  59. 59 else {
  60. 60 fileList1.value.push(options.file)
  61. 61 }
  62. 62 fileList.value = fileList1.value;
  63. 63 }
  64. 64
  65. 65 const removeFile = () => {
  66. 66 fileList.value = [];
  67. 67 fileList1.value = [];
  68. 68 progress.value.curr = 0;
  69. 69 }
  70. 70
  71. 71
  72. 72 const create = () => {
  73. 73 const formData = new FormData()
  74. 74 fileList1.value.forEach((file: any) => {
  75. 75 console.log(file)
  76. 76 formData.append('files', file)
  77. 77 })
  78. 78
  79. 79 http.post("task/create/", formData, {
  80. 80 headers: { "Content-Type": "multipart/form-data" }, onUploadProgress(progressEvent: any) {
  81. 81 progress.value.curr = Math.round((progressEvent.loaded * 100) / progressEvent.total)
  82. 82 if (progress.value.curr == 100) { progress.value.color = 'green' }
  83. 83 else { progress.value.color = 'orange' }
  84. 84 },
  85. 85 }).then((res: any) => {
  86. 86 if (res.code == 0) {
  87. 87 public_elmsg_success("任务创建成功")
  88. 88 }
  89. 89 else { public_elmsg_error(res.msg) }
  90. 90 }
  91. 91 );
  92. 92 }
  93. 93 </script>

v3版本的 djagno 代码 

  1. 1 from loguru import logger
  2. 2 from django.http.response import JsonResponse
  3. 3 from django.views.decorators.csrf import csrf_exempt
  4. 4
  5. 5 @csrf_exempt
  6. 6 def create_task(request):
  7. 7 files = request.FILES.getlist('files')
  8. 8 for fit in files:
  9. 9 logger.info(f"name: {fit.name} size: {round(fit.size/ 1024 / 1024 / 1024, 5)} G")
  10. 10 # 保存文件
  11. 11 # with open(f"{os.sep.join(['.', fit['name']])}", mode="wb") as f:
  12. 12 # f.write(fit)
  13. 13
  14. 14 return JsonResponse({"code": 0, "msg": "success"})

 

还有什么更好的方法 ,欢迎大家讨论哇

原文链接:https://www.cnblogs.com/gwt805/p/17955473

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号