• [Python自学] day-23 (2) (文件上传、验证码、KindEditor)


    一、文件上传

    文件上传有4种方式。

    1.表单形式上传

    略,表单形式上传要刷新页面。

    2.原生Ajax上传

    HTML代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>UPLOAD</title>
    </head>
    <body>
        <input type="file" id='select_file' value="选择文件"/>
        <input type="button" value="上传" onclick="up_load_file();" />
    
        <script>
            function up_load_file(){
                // 获取文件对象(整个文件)
                var file_obj = document.getElementById("select_file").files[0];
                var xhr = new XMLHttpRequest();
                xhr.open('POST',"/up_load_by_ajax/",true);
                // 回调函数
                xhr.onreadystatechange = function(){
                    if(xhr.readyState == 4){
                        var obj = JSON.parse(xhr.responseText);
                        console.log(obj);
                    }
                }
                // 使用FormData对象来封装POST数据(包含文件内容),文件必须要通过该对象封装
                var fd = new FormData();
                // 将需要发送的文本、文件数据都append到FormData对象中
                fd.append("username",'leo');
                fd.append("fafafa",file_obj);
                // 发送POST请求
                xhr.send(fd);
            }
        </script>
    </body>
    </html>

    视图函数:

    # 上传文件页面
    def up_load(request):
        return render(request,'up_load.html')
    
    
    # 响应ajax请求
    def up_load_by_ajax(request):
        if request.method == 'POST':
            name = request.POST.get("username")
            # 获取文件对象
            file_obj = request.FILES.get("fafafa")
            # 将文件内容存放到服务器
            with open(file_obj.name,'wb') as f:
                for item in file_obj.chunks():
                    f.write(item)
    
            ret = {'code': True, 'data': name}
            import json
            # 返回JSON数据
            return HttpResponse(json.dumps(ret))

    3.jQuery AJAX上传

    HTML代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>UPLOAD</title>
    </head>
    <body>
        <input type="file" id='select_file' value="选择文件"/>
        <input type="button" value="上传jq" onclick="up_load_file_jq();" />
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
            function up_load_file_jq() {
                var file_obj = document.getElementById("select_file").files[0];
                // 将需要发送的文本、文件数据都append到FormData对象中
                var fd = new FormData();
                fd.append("username",'leo');
                fd.append("fafafa",file_obj);
                $.ajax({
                    url: '/up_load_by_ajax/',
                    type: 'POST',
                    data: fd,  // jQuery会默认对数据进行处理,例如拼接成一个字符串。如果要传递对象,则要告诉jQuery别处理,用下面两个参数
                    processData:false,  // 告诉jQuery不要处理data中的数据
                    contentType:false,  // 告诉jQuery不要设置contentType
                    success: function (data, str, xhr_obj) {
                        console.log(data);
                        //console.log(typeof (str)); //打印success(string)
                        //console.log(xhr_obj);
                    }
                })
            }
        </script>
    </body>
    </html>

    视图函数:

    # 上传文件页面
    def up_load(request):
        return render(request,'up_load.html')
    
    
    # 响应ajax请求
    def up_load_by_ajax(request):
        if request.method == 'POST':
            name = request.POST.get("username")
            # 获取文件对象
            file_obj = request.FILES.get("fafafa")
            # 将文件内容存放到服务器
            with open(file_obj.name,'wb') as f:
                for item in file_obj.chunks():
                    f.write(item)
    
            ret = {'code': True, 'data': name}
            import json
            # 返回JSON数据
            return HttpResponse(json.dumps(ret))

    4.利用iframe上传文件

    HTML代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>UPLOAD</title>
    </head>
    <body>
        <form action="/up_load_by_ajax/" method="post" target="ifm1" enctype="multipart/form-data">
            <iframe name="ifm1" id="ifm1" ></iframe>
            <input type="file" name="fafafa" value="选择文件"/>
            <input type="submit" name="Form提交" onclick="iframe_up_load();"/>
        </form>
    
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
            function iframe_up_load(){
                //为iframe绑定onload事件函数,当数据回来时,则会触发
                $("#ifm1").load(function(){
                    //在这里去获取数据
                    var text = $("#ifm1").contents().find('body').text();
                    console.log(text);
                    var obj = JSON.parse(text);
                    // 拿到obj后,就可以随意处理数据了
                    //todo..
                })
            }
        </script>
    </body>
    </html>

    视图函数:

    from django.views.decorators.clickjacking import xframe_options_exempt
    
    
    # 响应ajax请求
    @xframe_options_exempt
    def up_load_by_ajax(request):
        if request.method == 'POST':
            name = request.POST.get("username")
            # 获取文件对象
            file_obj = request.FILES.get("fafafa")
            # 将文件内容存放到服务器
            with open(file_obj.name, 'wb') as f:
                for item in file_obj.chunks():
                    f.write(item)
    
            ret = {'code': True, 'data': name}
            import json
            # 返回JSON数据
            return HttpResponse(json.dumps(ret))

    在iframe中,为了防止报错,还是要加上装饰器@xframe_options_exempt。

    5.各种文件上传方式的优缺点

    1)表单上传需要刷新页面,不是很好。

    2)原生Ajax和jQuery AJax都要依赖FormData对象,低版本的浏览器可能不支持。

    3)ifame兼容性最好,一般上传图片、头像什么的都用iframe。

    二、预览功能

    使用iframe上传图片后,我们需要预览图片。

    首先在html中加上一个用于预览图片的div:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>UPLOAD</title>
    </head>
    <body>
        <!-- 添加一个预览图片的区域 -->
        <div id="preview"></div>
        <form action="/up_load_by_ajax/" method="post" target="ifm1" enctype="multipart/form-data">
            <!-- 将iframe的默认框隐藏了 -->
            <iframe name="ifm1" id="ifm1" style="display: none;"></iframe>
            <input type="file" name="fafafa" value="选择文件"/>
            <input type="submit" name="Form提交" onclick="iframe_up_load();"/>
        </form>
        
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
            function iframe_up_load(){
                $("#ifm1").load(function(){
                    // 从iframe框中获取响应的数据
                    var text = $("#ifm1").contents().find('body').text();
                    var obj = JSON.parse(text);
                    var imgTag = document.createElement('img')
                    // 获取到上传图片在服务器的路径,然后添加到预览区
                    imgTag.src = '/'+obj.img_path
                    $("#preview").append(imgTag)
                });
            }
        </script>
    </body>
    </html>

    视图函数中将图片的存储路径返回给浏览器:

    from django.views.decorators.clickjacking import xframe_options_exempt
    
    
    # 响应ajax请求
    @xframe_options_exempt
    def up_load_by_ajax(request):
        if request.method == 'POST':
            name = request.POST.get("username")
            # 获取文件对象
            file_obj = request.FILES.get("fafafa")
    
            file_name = file_obj.name
            import os
            img_path = os.path.join("static/imgs/",file_name)
            print(img_path)
            # 将文件内容存放到服务器
            with open(img_path, 'wb') as f:
                for item in file_obj.chunks():
                    f.write(item)
            # 返回img_path
            ret = {'code': True, 'img_path': img_path}
            import json
            # 返回JSON数据
            return HttpResponse(json.dumps(ret))

    效果如下:

     如果对预览图片大小有要求,则使用样式限制img标签大小即可。如果想要节省图片传输带宽,则可以在服务器生成大小固定的缩略图,然后返回缩略图的path即可。

    三、图片验证码

    图片验证码流程图:

    1)用户请求login页面,页面返回。显示验证码的img标签会再次请求一个验证码图片(专门的url,对应一个生成验证码的视图函数)。

    2)在视图函数生成验证码的同时,会将生成内容的文本形式存放到用户对应的session中。并将图片形式,以二进制的形式返回给页面,页面将图片显示在img标签中。

    3)用户根据图片中的验证码输入,并通过Ajax提交给后台验证,后台将用户输入与session中保存的验证码比对。

    4)比对正确,验证通过,比对不正确,验证失败。

    注意:在一般使用验证码的地方,我们都可以通过鼠标点击验证码图片进行换一张操作。其实就是让img标签重新请求一个验证码图片,并在session中更新为新的图片内容。

    1.img标签请求动态验证码

    我们一般使用img标签是这样的:

    <img src="/static/imgs/xxxx.png">

    也就是显示静态文件xxxx.png。

    其实,我们也可以使用动态生成的图片数据:

    img.html页面:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>IMG</title>
    </head>
    <body>
        <div>
            <img src="/gener_img/">
        </div>
    </body>
    </html>

    img视图函数:

    def img(request):
        return render(request, "img.html")

    gener_img视图函数:

    def gener_img(request):
        with open("static/imgs/验证码.png", 'rb') as f:
            img = f.read()
        return HttpResponse(img)

    当我们请求img.html页面时,img标签会自动请求gener_img页面(对应gener_img视图函数),视图函数动态的读取static/imgs/验证码.png并返回(后续会自动生成验证码)。

    效果:

    2.生成验证码

    要生成验证码,一般要完成以下几个步骤:

    1)创建一张图片。借助Pillow模块。

    2)在图片中写入随机字符串

    3)在图片画随机干扰线

    4)在图片画随机干扰点

    安装pillow:

    pip install pillow

    在工程目录下创建utils/tools.py(用于存放常用工具类和函数):

    代码参照:https://www.cnblogs.com/6324TV/p/8811249.html

    from PIL import Image, ImageDraw, ImageFont
    import random
    
    
    class ValidCodeImg(object):
        def __init__(self, width=150, height=30, code_count=5, font_size=32, point_count=20, line_count=3,
                     img_format='png'):
            '''
            可以生成一个经过降噪后的随机验证码的图片
            :param  图片宽度 单位px
            :param height: 图片高度 单位px
            :param code_count: 验证码个数
            :param font_size: 字体大小
            :param point_count: 噪点个数
            :param line_count: 划线个数
            :param img_format: 图片格式
            :return 生成的图片的bytes类型的data
            '''
            self.width = width
            self.height = height
            self.code_count = code_count
            self.font_size = font_size
            self.point_count = point_count
            self.line_count = line_count
            self.img_format = img_format
    
        @staticmethod
        def getRandomColor():
            '''获取一个随机颜色(r,g,b)格式的'''
            c1 = random.randint(0, 255)
            c2 = random.randint(0, 255)
            c3 = random.randint(0, 255)
            return (c1, c2, c3)
    
        @staticmethod
        def getRandomStr():
            '''获取一个随机字符串,每个字符的颜色也是随机的'''
            random_num = str(random.randint(0, 9))
            random_low_alpha = chr(random.randint(97, 122))
            random_upper_alpha = chr(random.randint(65, 90))
            random_char = random.choice([random_num, random_low_alpha, random_upper_alpha])
            return random_char
    
        def getValidCodeImg(self):
            # 获取一个Image对象,参数分别是RGB模式。宽150,高30,随机颜色
            image = Image.new('RGB', (self.width, self.height), self.getRandomColor())
    
            # 获取一个画笔对象,将图片对象传过去
            draw = ImageDraw.Draw(image)
    
            # 获取一个font字体对象参数是ttf的字体文件的目录,以及字体的大小
            font = ImageFont.truetype("static/KumoFont.ttf", size=self.font_size)
    
            temp = []
            for i in range(self.code_count):
                # 循环5次,获取5个随机字符串
                random_char = self.getRandomStr()
    
                # 在图片上一次写入得到的随机字符串,参数是:定位,字符串,颜色,字体
                draw.text((10 + i * 30, -2), random_char, self.getRandomColor(), font=font)
    
                # 保存随机字符,以供验证用户输入的验证码是否正确时使用
                temp.append(random_char)
            valid_str = "".join(temp)
    
            # 噪点噪线
            # 划线
            for i in range(self.line_count):
                x1 = random.randint(0, self.width)
                x2 = random.randint(0, self.width)
                y1 = random.randint(0, self.height)
                y2 = random.randint(0, self.height)
                draw.line((x1, y1, x2, y2), fill=self.getRandomColor())
    
            # 画点
            for i in range(self.point_count):
                draw.point([random.randint(0, self.width), random.randint(0, self.height)], fill=self.getRandomColor())
                x = random.randint(0, self.width)
                y = random.randint(0, self.height)
                draw.arc((x, y, x + 4, y + 4), 0, 90, fill=self.getRandomColor())
    
            # 在内存生成图片
            from io import BytesIO
            f = BytesIO()
            image.save(f, self.img_format)
            data = f.getvalue()
            f.close()
    
            return data, valid_str

    注意:以上代码中依赖一个字体文件 "static/KumoFont.ttf" ,我们需要实现准备该字体文件。

    在gener_img视图函数中调用ValidCodeImg类来生成验证码图片:

    from utils.tools import ValidCodeImg
    
    
    def gener_img(request):
        # 创建ValidCodeImg对象
        img = ValidCodeImg()
        # 生成验证码图片和文本
        img_data, valid_str = img.getValidCodeImg()
        # 将验证码的文本内容放入session中, 用于以后验证
        request.session['validcode'] = valid_str
        # 将验证码返回给页面
        return HttpResponse(img_data)

    效果:

    3.验证用户输入

    html中实现用户验证码输入框,以及ajax提交:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>IMG</title>
    </head>
    <body>
        <div>
            <img src="/gener_img/">
        </div>
        <div>
            <input type="text" id="validcode"/>
            <input type="button" value="验证" onclick="checkcode();"/>
            <label id="error_label"></label>
        </div>
    
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
            function checkcode(){
                // 获取text框中的验证码(用户输入)
                var vc = $("#validcode").val();
                // 发送ajax请求去验证
                $.ajax({
                    // 发送给/checkcode/页面
                    url: '/checkcode/',
                    // POST方法
                    type: 'POST',
                    // 验证码数据
                    data: {'code':vc},
                    // 回调函数,显示验证结果
                    success:function(data,str,xhr_obj) {
                        var json_data = JSON.parse(data);
                        var stat = json_data.status;
                        var err_label = $("#error_label");
                        // 如果成功显示验证码正确,如果失败显示错误信息
                        if(stat){
                            err_label.css('color','green');
                            err_label.text("验证码正确");
                        }else{
                            err_label.text(json_data.error_msg);
                            err_label.css('color','red');
                        }
                    }
                });
            }
        </script>
    </body>
    </html>

    实现验证码验证视图函数checkcode:

    # 验证图片验证码
    def checkcode(request):
        code = request.POST.get('code')
        cur_code = request.session.get('validcode')
        # 如果验证成功返回status:True,否则返回status:False
        if code != cur_code:
            ret = {'status': False, 'error_msg': '验证码不正确'}
        else:
            ret = {'status': True, 'error_msg': ''}
        import json
        return HttpResponse(json.dumps(ret))

    效果:

    4.点击切换验证码

    修改html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>IMG</title>
    </head>
    <body>
        <div>
            <img src="/gener_img/" onclick="changeCheckCode(this);">
        </div>
        <div>
            <input type="text" id="validcode"/>
            <input type="button" value="验证" onclick="checkcode();"/>
            <label id="error_label"></label>
        </div>
    
        <script src="/static/jquery-1.12.4.js"></script>
        <script>
            function checkcode(){
                // 获取text框中的验证码(用户输入)
                var vc = $("#validcode").val();
                // 发送ajax请求去验证
                $.ajax({
                    // 发送给/checkcode/页面
                    url: '/checkcode/',
                    // POST方法
                    type: 'POST',
                    // 验证码数据
                    data: {'code':vc},
                    // 回调函数,显示验证结果
                    success:function(data,str,xhr_obj) {
                        var json_data = JSON.parse(data);
                        var stat = json_data.status;
                        var err_label = $("#error_label");
                        // 如果成功显示验证码正确,如果失败显示错误信息
                        if(stat){
                            err_label.css('color','green');
                            err_label.text("验证码正确");
                        }else{
                            err_label.text(json_data.error_msg);
                            err_label.css('color','red');
                        }
                    }
                });
            }
    
            function changeCheckCode(ths){
                ths.src= ths.src + '?';
            }
    
        </script>
    </body>
    </html>

    注意,在验证码图片的onclick事件函数中,每次给img的src属性多加一个"?",这样每次设置的src与上一次的src不一样,浏览器会自动去请求新的URL。否则不动。

    四、KindEditor

    KindEditor是一个富文本编辑框。

    1.下载KindEditor

    下载地址:https://github.com/kindsoft/kindeditor/releases/download/v4.1.11/kindeditor-4.1.11-zh-CN.zip

    解压后有以下文件:

    其中红框部分可以删除(都是些各种语言的实例文件)。留下语言、插件和主题文件,以及JS文件。

    将删除后的文件夹拷贝到项目的/static目录下备用。

    2.使用KindEditor

    HTML代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Kind</title>
    </head>
    <body>
        <div style=" 800px;margin: 0 auto;">
            <textarea name="content" id="content"></textarea>
        </div>
    
        <script src="/static/jquery-1.12.4.js"></script>
        <script src="/static/kindeditor/kindeditor-all.js"></script>
        <script>
            $(function(){
                initKind();
            });
            
            function initKind(){
                var kind = KindEditor.create("#content",{
                    "100%",
                    height:"300px",
                    minWidth:200,
                    minHeight:400
                });
            }
        </script>
    </body>
    </html>

    视图函数:

    def kind(request):
        return render(request,'kind.html')

    效果:

     在初始化中,除了高宽等参数,还有很多可用的参数。

    参照中文文档:http://kindeditor.net/docs/option.html

    在初始化参数中,我们注意几个常用的参数:

    items:

    [
            'source', '|', 'undo', 'redo', '|', 'preview', 'print', 'template', 'code', 'cut', 'copy', 'paste',
            'plainpaste', 'wordpaste', '|', 'justifyleft', 'justifycenter', 'justifyright',
            'justifyfull', 'insertorderedlist', 'insertunorderedlist', 'indent', 'outdent', 'subscript',
            'superscript', 'clearhtml', 'quickformat', 'selectall', '|', 'fullscreen', '/',
            'formatblock', 'fontname', 'fontsize', '|', 'forecolor', 'hilitecolor', 'bold',
            'italic', 'underline', 'strikethrough', 'lineheight', 'removeformat', '|', 'image', 'multiimage',
            'flash', 'media', 'insertfile', 'table', 'hr', 'emoticons', 'baidumap', 'pagebreak',
            'anchor', 'link', 'unlink', '|', 'about'
    ]

    这个参数是一个列表,用于指定富文本框的工具栏菜单。我们可以从中选择我们需要的功能进行显示。

    noDisableItems:

    配合designMode:false,可以让选中的功能可用,其他不可用:

    noDisableItems:["source","fullscreen"],
    designMode:false

    效果:

     除了source和fullscreen两个功能,其他全部禁用。

    htmlTags:

    可以使用的HTML标签的白名单。其他被过滤掉(但不是绝对的,所以还需要在后台进行验证过滤)。

    sizeType:

    编辑框的宽高是否可变。2表示宽高都可以变,1表示只能变高度,0表示不能动。

    3.KindEditor上传图片

    在KindEditor的初始化参数中,有一个uploadJson参数,可以参数用于配置上传图片时请求的URL

    function initKind(){
        var kind = KindEditor.create("#content",{
            "100%",
            height:"300px",
            minWidth:200,
            minHeight:400,
            uploadJson:"/upload_img/"
        });
    }

    对应视图函数:

    @xframe_options_exempt
    def upload_img(request):
        # 使用imgFile来获取图片(KindEditor指定的),可以使用filePostName参数来修改。
        img_file = request.FILES.get("imgFile")
        import os
        img_path = os.path.join("static/imgs/", img_file.name)
        print(img_file.name)
        with open(img_path, 'wb') as f:
            for i in img_file.chunks():
                f.write(i)
    
        print('/' + img_path)
        # 这是固定返回给kindeditor的格式,error为0表示正常,url是图片保存的位置/static/imgs/xxx.png,message表示错误信息
        dict = {
            'error': 0,
            'url': '/' + img_path,
            'message': ''
        }
        import json
        return HttpResponse(json.dumps(dict))

    因为KindEditor上传图片使用的是iframe,所以要使用@xframe_options_exempt 装饰器。

    效果:

    注意:这里上传图片时可以选择 "本地上传" 是通过参数 allowImageUpload 来指定的,默认为true,如果为false,则不提供本地上传。

    注意:在视图函数中,我们使用"imgFile"来获取上传的图片文件。这个名称是可以修改的:

    // 初始化参数中添加
    filePostName:"upload_file",

    再获取的时候:

    file_obj = request.FILES.get("upload_file")

    4.KindEditor上传其他类型文件

    除了上传图片,KindEditor还可以上传其他类型的文件,例如flash、视音频、地图等。

    实际上,这些文件都是向uploadJson指定的URL提交的。从F12中可以看到:

    当我们上传图片的时候,后面带着一个GET请求参数,"?dir=image"。表示我们上传的是图片(利用上传图片功能上传)。如果上传其他类型,这里的参数值会根据上传类型来改变。

    例如,我们使用上传flash功能:

    这样,我们在视图函数中,可以通过GET中的dir数据来判断上传的什么文件。

    也就是说,我们在处理上传文件时,只需要判断文件类型,并放置到不同的目录中即可:

    @xframe_options_exempt
    def upload_img(request):
        import os
        file_obj = request.FILES.get("imgFile")
        file_type = request.GET.get('dir')
        if file_type == "image":
            # 使用imgFile来获取图片(KindEditor指定的)
            file_path = os.path.join("static/imgs/", file_obj.name)
        elif file_type == "file":
            file_path = os.path.join("static/uploads/", file_obj.name)
        elif file_type == "flash":
            file_path = os.path.join("static/flashes/", file_obj.name)
        # 写入文件
        with open(file_path, 'wb') as f:
            for i in file_obj.chunks():
                f.write(i)
        # 这是固定返回给kindeditor的格式,error为0表示正常,url是文件保存的位置/static/imgs/xxx.png,message表示错误信息
        dict = {
            'error': 0,
            'url': '/' + file_path,
            'message': ''
        }
        import json
        return HttpResponse(json.dumps(dict))

    注意:

    和上传图片一样,也有几个参数来控制是否允许上传。例如:

    allowFlashUpload :默认为true,允许上传Flash。

    allowMediaUpload:默认为true,允许上传音视频。

    allowFileUpload:默认为true,允许上传文件。

    allowImageRemote:默认为true,允许网络URL图片。

    如果为false,则变为只有本地上传:

    5.FileManager文件管理

    在初始化参数中,加上以下配置:

    allowFileManager:true,  // 允许使用FileManager功能
    fileManagerJson:"/file_manager/"  // 设置请求路径

    设置好后,我们打开文件上传或图片上传时:

    可以看到多了一个"文件空间"。这就是FileManager提供的管理空间。

    注意,图片上传一定要开启allowImageRemote:true,才能看到"图片空间"

    视图函数实现:

    参考:https://www.cnblogs.com/wupeiqi/articles/6307554.html

    import os
    import json
    import time
    
    
    def file_manager(request):
        """
        文件管理
        :param request:
        :return:
        """
        dic = {}
        root_path = 'D:/pycharm_workspace/day22/static/'
        static_root_path = '/static/'
        request_path = request.GET.get('path')
        if request_path:
            abs_current_dir_path = os.path.join(root_path, request_path)
            move_up_dir_path = os.path.dirname(request_path.rstrip('/'))
            dic['moveup_dir_path'] = move_up_dir_path + '/' if move_up_dir_path else move_up_dir_path
    
        else:
            abs_current_dir_path = root_path
            dic['moveup_dir_path'] = ''
    
        dic['current_dir_path'] = request_path
        dic['current_url'] = os.path.join(static_root_path, request_path)
    
        file_list = []
        for item in os.listdir(abs_current_dir_path):
            abs_item_path = os.path.join(abs_current_dir_path, item)
            a, exts = os.path.splitext(item)
            is_dir = os.path.isdir(abs_item_path)
            if is_dir:
                temp = {
                    'is_dir': True,
                    'has_file': True,
                    'filesize': 0,
                    'dir_path': '',
                    'is_photo': False,
                    'filetype': '',
                    'filename': item,
                    'datetime': time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(os.path.getctime(abs_item_path)))
                }
            else:
                temp = {
                    'is_dir': False,
                    'has_file': False,
                    'filesize': os.stat(abs_item_path).st_size,
                    'dir_path': '',
                    'is_photo': True if exts.lower() in ['.jpg', '.png', '.jpeg'] else False,
                    'filetype': exts.lower().strip('.'),
                    'filename': item,
                    'datetime': time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(os.path.getctime(abs_item_path)))
                }
    
            file_list.append(temp)
        dic['file_list'] = file_list
        return HttpResponse(json.dumps(dic))

    实现效果:

    6.添加额外参数(例如CSRF)

    如果存在CSRF问题(POST请求时),则可以在参数中添加:

    extraFileUploadParams:{
        csrfmiddlewaretoken:{{csrf_token}}
    }

    完整代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Kind</title>
    </head>
    <body>
        <form>
            {% csrf_token %}
            <div style=" 800px;margin: 0 auto;">
                <textarea name="content" id="content"></textarea>
            </div>
        </form>
        <script src="/static/jquery-1.12.4.js"></script>
        <script src="/static/kindeditor/kindeditor-all.js"></script>
        <script>
            $(function(){
                initKind();
            });
    
            function initKind(){
                var kind = KindEditor.create("#content",{
                    "100%",
                    height:"300px",
                    minWidth:200,
                    minHeight:400,
                    uploadJson:"/upload_img/",
                    allowFileManager:true,
                    fileManagerJson:"/file_manager/",
                    extraFileUploadParams:{
                        csrfmiddlewaretoken:"{{ csrf_token }}"
                    }
                });
            }
        </script>
    </body>
    </html>

    这样就可以正常使用CSRF了。

     (─‿‿─)

    D:pycharm_workspaceday22static

  • 相关阅读:
    【Node.js 自己封装的库 http_parse, libuv】
    select遍历list默认选中初始值
    mybatis入门基础----高级映射(一对一,一对多,多对多)
    工具类 | window批处理杀死指定端口进程
    eclipse 关闭控制台 自动弹出
    mybatis的jdbcType和javaType、oracle,MySQL的对应类型
    mysql 创建表格 AUTO_INCREMENT
    Linux shell脚本启动 停止 重启jar包
    Tomcat结合nginx使用小结
    集成maven和Spring boot的profile功能
  • 原文地址:https://www.cnblogs.com/leokale-zz/p/12158342.html
Copyright © 2020-2023  润新知