Django目录上传——ajax批量上传,下载文件

涉及知识点:

  • file类型的input框,设置多选文件或者上传整个目录
  • 第三方jquery库取cookie
  • ajax批量上传文件,formData()取到form中的数据

前端库下载地址:https://www.bootcdn.cn/
参考:https://blog.csdn.net/leaves_story/article/details/80416853

需求:通过ajax实现目录下所有文件的上传

1.前端代码
使用ajax的目的:使页面在不刷新的基础上批量上传文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ajax大量文件上传</title>
    <script src="/static/js/jquery3.4.1.js"></script>
    <script src="/static/js/jquery.cookie.js"></script>
</head>
<body>
<form action="/test1/upload_dir/" enctype="multipart/form-data" method="post" id="formUploadDir">
    {% csrf_token %}
    <!-- webkitdirectory:设置目录上传,貌似仅支持chrome -->
    <input type="file" name="files" id="uploadDir" webkitdirectory>
    <button>form表单上传</button>
</form>

<input type="button" value="ajax提交" id="ajaxUploadDirBtn">

<!-- multiple:允许同时上传多个文件 -->
<p><input type="file" name="files" id="uoloadfiles" multiple></p>

</body>
<script>
    $(function () {
        $("#ajaxUploadDirBtn").click(function () {
            // 构造表单对象,构造时传参必须传入form节点对象
            // $("#formUploadDir")取到的是form对象的一个数组,然后通过索引取到对应form中的数据
            var formData = new FormData($("#formUploadDir")[0]);
            // 取到cookie中csrf的值,依赖第三方jquery库
            var token = $.cookie("csrftoken");
            // 判断上传的目录是否为空,非空时files对应目录中第一个文件的路劲
            // C:\fakepath\desktop.ini:浏览器为了安全,不暴露客户端的完整文件路径
            var files = $("#uploadDir").val();
            if(files==""){
                alert("请选择要上传的目录或该目录为空")
                return
            }
            $.ajax({
                url: '/test1/upload_dir/',
                type: 'post',
                data: formData,
                headers: token,    // django默认阻止post请求,带上csfr_token
                async: false,
                cache: false,
                // 告诉jquery不用设置Content-Type请求头
                contentType: false,
                // 告诉jquery不用去处理发送的数据
                processData: false,
                success: function (resp) {
                    alert("OK")
                },
                error: function (resp) {
                    alert('error')
                }
            })
        })
    })
</script>
</html>

2.后端上传代码
form表单提交和ajax提交,后端逻辑是一样的

import os
from django.shortcuts import render, HttpResponse

UPLOAD_PATH = 'D:\\test1\\'
# Create your views here.
def files_upload(request):
    if request.method == 'GET':
        return render(request, 'filesupload.html')
    elif request.is_ajax():
        # 根据input框的name属性值取到文件对象
        files = request.FILES.getlist('files')
        for file in files:
            # 获取文件名,文件对象的__str__属性返回的是文件名
            file_name = str(file)
            with open(os.path.join(UPLOAD_PATH, file_name), 'wb') as f:
                # 分块写入,防止大文件卡死
                for chunk in file.chunks(chunk_size=2014):
                    f.write(chunk)
        return HttpResponse('ajaxOK')

3.后端下载FileResponse
HttpResponse有个很大的弊端,其工作原理是先读取文件,载入内存,然后再输出。如果下载文件很大,该方法会占用很多内存。对于下载大文件,Django更推荐StreamingHttpResponse和FileResponse方法,这两个方法将下载文件分批(Chunks)写入用户本地磁盘,先不将它们载入服务器内存。

def download_file(request):
    id_ = request.POST.get('id')
    file_obj = UploadFile.objects.get(id=id_)
    filename = file_obj.file_name
    # 文件将会自动关闭,所以不能使用with语句打开文件
    fr = open(os.path.join(FILEDIR, filename), 'rb')
    # 接受二进制内容
    response = FileResponse(fr)
    # 设置参数,使客户端直接下载到磁盘上
    response['content_type'] = "application/octet-stream"
    response['Content-Disposition'] = 'attachment; filename="%s"' % filename
    return response
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值