ElementUI + Vue + Django 上传文件

     阅读:26

为了实现django的文件上传存储,参考了许多博客。
目前觉得这篇博客:Django(drf)配合 Vue Element 实现文件上传下载功能的实现较为优雅

但其它方法也有可借鉴的地方,特此记录

0. 主要参考

[1] Element文档:Upload 上传
[2] 肖祥:ElementUI 上传文件以及限制
[3] PythonNew_Mr.Wang:【Django后端分离】使用element-ui文件上传

1. 环境配置

首先安装相应的包

Django == 3.1.5
djangorestframework == 3.11.1
django-cors-headers == 3.5.0   #解决跨域问题

修改settings.py解决跨域问题
具体操作见参考[2]

2. 前端代码

使用Element提供的样例
只要将<el-upload>组件的参数action = " "设为相应的后端上传文件接口

3. 后端代码

方案一

简单写法,上传任意文件,返回文件在服务器端存储的路径(代码中将文件改名为head)

## urls.py

urlpatterns = [
	# 定义文件上传接口
	path('api/upload/', views.upload),
]

## view.py

def upload(request):
    """上传文件"""
    # 获取相对路径
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    if request.method == 'POST':
        file = request.FILES.get('file', None)
        # 设置文件上传文件夹
        head_path = BASE_DIR + "\\upload\\json"
        print("head_path", head_path)
        # 判断是否存在文件夹, 如果没有就创建文件路径
        if not os.path.exists(head_path):
            os.makedirs(head_path)
        file_suffix = file.name.split(".")[1]  # 获取文件后缀
        # 储存路径
        file_path = head_path + "\\{}".format("head." + file_suffix)
        file_path = file_path.replace(" ", "")
        # 上传文件
        with open(file_path, 'wb') as f:
            for chunk in file.chunks():
                f.write(chunk)

        message = {}
        message['code'] = 200
        # 返回图片路径
        message['fileurl'] = file_path

        return JsonResponse(message)

方案二

这里限定上传json文件,且大小不超过5M
将上传的json文件随机命名,返回新的文件名。

路由映射

## urls.py

urlpatterns = [
	# json文件上传接口
	path('file/json_upload/',views.File.as_view())
]

视图函数

## views.py

from rest_framework.views import APIView
from upload_demo import settings
from django.shortcuts import render, redirect, HttpResponse
from django.http import JsonResponse
from rest_framework import status
import os
import uuid


class File(APIView):
    def post(self, request):
        print(request.FILES)
        # 接收文件
        file_obj = request.FILES.get('file', None)
        print("file_obj", file_obj.name)

        # 文件上传至根目录/upload/json文件夹下
        head_path = os.path.join(settings.BASE_DIR, 'upload/json')
        print("head_path", head_path)
        # 判断是否存在文件夹
        # 如果没有就创建文件路径
        if not os.path.exists(head_path):
            os.makedirs(head_path)

        # 判断文件大小不能超过5M
        if file_obj.size > 5242880:
            return JsonResponse({'status': status.HTTP_403_FORBIDDEN, 'msg': '文件过大'},
                                status=status.HTTP_403_FORBIDDEN)

        # 文件后缀
        suffix = file_obj.name.split(".").pop()
        print("文件后缀", suffix)

        # 判断文件后缀
        suffix_list = ["json"]
        if suffix not in suffix_list:
            return JsonResponse({'status': status.HTTP_403_FORBIDDEN, 'msg': '只能选择json文件'},
                                status=status.HTTP_403_FORBIDDEN)

        # 重命名文件
        file_name = '%s.%s' % (uuid.uuid4(), suffix)
        print("file_name", file_name)
        # 储存路径
        file_path = os.path.join(head_path, file_name)
        print("储存路径", file_path)

        # 写入文件到指定路径
        with open(file_path, 'wb') as f:
            for chunk in file_obj.chunks():
                f.write(chunk)

        data = {}
        data['name'] = file_name
        return JsonResponse({'status': status.HTTP_200_OK, 'data': data}, status=status.HTTP_200_OK)

4. 其它参考

查阅的其它的一些资料,可能会有用,先存在这里
https://docs.djangoproject.com/en/3.1/topics/http/file-uploads/
https://blog.csdn.net/weixin_42134789/article/details/80753051