美文网首页
django中文件上传与图片处理

django中文件上传与图片处理

作者: barriers | 来源:发表于2019-04-02 17:04 被阅读0次

    1前端文件上传

    <p>上传单张图片</p>
    <form action="/baby/get_text/" method="post" enctype="multipart/form-data">
       <input type="file" name="sub_file" id="sub_files" />
       <p><input type="submit" value="上传"></p>
    </form>
    

    前端获取路由中的参数的方法

    var search = document.location.search
    id = search.split('=')[1]
    

    2后端文件接收

    2.1后端接收文件并写入excel文件及写入数据库

    file = request.FILES.get("sub_file"):拿到文件对象;name_back = file.content_type获取文件的格式;name_fol = file.name拿到文件名字;file.size获取文件大小;file.read() 从文件中读取整个上传的文件,这个方法只适合小文件;file.chunks() 按块返回二进制文件,结果为一个生成器,通过for循环进行迭代,可以将大文件按块写入文件中,可以指定一次读的长度,不指定就是默认全部;file.multiple_chunks() 根据file文件的大小,返回true或者false,当文件大于2.5M(默认大小,可以自己设定)时,返回true否则返回false。因此可以根据该方法来选择选用read方法读取还是采用chunks方法
    file中的文件都是二进制文件,在写入另一个文件中时,另一个文件必须以二进制wb的方式写入

    def get_text(request):
        file = request.FILES.get("sub_file")
        print(file)
        BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        name_back = file.content_type # text/plain,文件格式
        name_fol = file.name # yob1883.txt,文件名
        str1 = file.file # <_io.BytesIO object at 0x000001DCECE26678>;
        print(name_back, name_fol, str1)
        # 创建表格并创建sheet
        xls = xlwt.Workbook()
        sht1 = xls.add_sheet(name_fol.split('.')[0])
        # 打开文件
        with open(os.path.join(BASE_DIR, 'media', 'excel', name_fol), 'wb') as f:
            # file = request.FILES.get("sub_file") file为上传文件的包装,需要另外使用其他方法才能拿到真实文件和其他属性
            # file.content_type  获取文件格式 text/plain
            # file.name 获取文件名 yob1883.txt
            # file.size获取文件大小
            # file中的文件都是二进制文件,在写入另一个文件中时,另一个文件必须以二进制wb的方式写入
            # file.read() 从文件中读取整个上传的文件,这个方法只适合小文件
            # file.chunks() 按块返回二进制文件,结果为一个生成器,通过for循环进行迭代,可以将大文件按块写入文件中,可以指定一次读的长度,不指定就是默认全部
            # file.multiple_chunks() 根据file文件的大小,返回true或者false,当文件大于2.5M(默认大小,可以自己设定)时,返回true否则返回false。因此可以根据该方法来选择选用read方法读取还是采用chunks方法
            for txt in file.chunks():
                # 写成txt文档
                f.write(txt)
                txt = str(txt)[2:] # 将二进制文件转换为字符串并去除字符串前面的b'
                txt = txt.replace('\\n', '').split('\\r') # 对字符串进行切割和替换
                txt = [line.split(',') for line in txt][:-1] # 去除最后的空列表
                # 保存数据到excel文件中
                for index, item in enumerate(txt):
                    # 保存数据到数据库中
                    baby = Baby()
                    baby.name = item[0]
                    baby.gender = item[1]
                    baby.freq = item[2]
                    baby.save()
                    # 保存数据到excel文件中
                    for i, j in enumerate(item):
                        sht1.write(index, i, j)
                        print(j)
                xls.save(os.path.join(BASE_DIR, 'media', 'excel', './姓名.xls'))
    
        return JsonResponse({"status_code": 200, "message": "上传成功"})
    

    2.2按行读文件

    按行读取文件(当文件较大时,常使用,防止内存被大量占用)

    with open('../babynames/yob1880.txt', 'r', encoding='utf8') as f:
        for line in f:
            text = line.replace('\n', '').split(',')
            print(text)
    

    2.3写入excel文件

    import xlwt
    xls = xlwt.Workbook() # 创建excel对象
    sht1 = xls.add_sheet(‘表格1’) # 创建sheet对象并取名
    for index, item in enumerate(txt):
        for i, j in enumerate(item):
            sht1.write(index, i, j) # index和i表示第几行第几列,j表示写入的数据
    xls.save(os.path.join(BASE_DIR, 'media', 'excel', './姓名.xls'))
    

    2.4从excel中读内容

    import xlrd
    data = xlrd.open_workbook(r'./20190326gzzwtjb.xlsx') 打开表格
    # table = data.sheets()[0]
    table = data.sheet_by_index(0) 获取第一个sheet表格
    nrows = table.nrows 查看行数
    table.ncols 查看列数
    for i in range(nrows):
        print(table.row_values(i)) # 读取每行内容
    print(table.cell(5,5).value) #获取单元格内容
    

    xlrd和xlwt只能对excel进行相应的读或者写操作;xlutils结合xlrd可以达到修改excel文件目的;openpyx可以对excel文件进行读写操作;xlsxwriter可以写excel文件并加上图表

    3django传输和保存多张图片

    3.1前端html代码

    <p>上传多张图片</p>
    <form action="/baby/get_img/" method="post" enctype="multipart/form-data">
      <div class="input-file-box">
        <input type="file" name="sub_file" id="fileup" multiple="multiple" onclick="fileLoad();">
      </div>
      <p><input type="submit" value="上传"></p>
    </form>
    

    在input中除了type="file"外;还要添加multiple="multiple"才表示上传多个文件

    3.2前端js代码获取多个文件

    <script type="text/javascript">
      function fileLoad() {
        fileup.onchange = function () {
            $.each($(fileup.files), function (index, val) {
                var reader = new FileReader();
                reader.onload = function () {
                    console.log(this.result)
                    var img = document.createElement('img');
                    img.src = this.result;
                    document.body.append(img);
                    console.log(val)
                    document.body.innerHTML += val.name;
                    document.body.innerHTML += val.lastModifiedDate;
                    document.body.innerHTML += (val.size/1024).toFixed(1)+'K';
                }
            });
         }
      }
    </script>
    

    上面js代码功能是选择多个文件,没有上面的js代码,一次只能选一个文件;要上传文件需要用submit表单提交或者用ajax提交。

    3.3后端代码

    def get_list_img(request):
        # img_files = request.FILES.getlist("images", "") # 获取不同name的图片
        files = request.FILES.getlist("sub_file") # 获取相同name的图片
        print(files)
        BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        for file in files:
            print(file)
            name_back = file.content_type # text/plain,文件格式
            name_fol = file.name # yob1883.txt,文件名
            str1 = file.file # <_io.BytesIO object at 0x000001DCECE26678>;
            print(name_back, name_fol, str1)
            # 打开文件
            with open(os.path.join(BASE_DIR, 'media', 'img', name_fol), 'wb') as f:
                for img in file.chunks():
                    # 写成txt文档
                    f.write(img)
    
        return JsonResponse({"status_code": 200, "message": "上传成功"})
    

    获取多个文件时用request.FILES.getlist才能获取到上传的全部文件。

    4图片处理

    图片处理使用Pillow库
    os.listdir('big_img') 将big_img文件夹中的所有文件名组成一个列表
    os.remove('文件名') 将文件名对应的文件删除
    from PIL import Image
    im = Image.open(im_path) 打开图片,open内为路径
    width, height = img.size 获取图片尺寸
    resizedIm = im.resize((width, height+(1920-1080))) 重新设置图片至指定宽高,括号内需传入一个元祖
    resizedIm.save(r'C:\Users\Administrator\Desktop\resize.jpg') 重新保存
    resizedIm.save(img_name, quality=95) quality表示图片压缩度,默认75,范围一般为1(最差)-95(最佳)
    smal_pict = pict.crop((num[0]i/4, 0, (i+1)num[0]/4, num[1]/4))对图片的左上角及右下角围成的区域进行裁剪形成一个新对象,对其使用smal_pict.save('名字')即可保存为新图片
    screenshot = browser.get_screenshot_as_png() 截屏
    screenshot = Image.open(BytesIO(screenshot)) 生成截屏的图的对象
    screenshot.save('./bijiao/big/big_image.png') 将截屏对象保存为图片
    pic.rotate(270)将图片对象逆时针旋转270度

    5文件压缩与解压

    5.1压缩

    import zipfile
    zp = zipfile.ZipFile(path,'w') 以写的方式打开path路径的压缩文件;
    zp.write(filename,os.path.basename(filename)) 将文件filename写入压缩文件
    zp.close()关闭

    5.2解压

    zp = zipfile.ZipFile(zipfilepath) 解压zipfilepath路径的文件
    zp.extractall(unzipfilepath)解压所有到unzipfilepath路径下
    zp.close()关闭
    详细信息见 https://blog.csdn.net/weixin_41202652/article/details/78988934

    统计列表中的元祖的第二个值出现的次数

    list3.sort(key=lambda x: x[0]) # 对列表按列表中元祖的第一个元素进行排序,原列表将会被改变
    dict1 = {}
    for index in list4:
        num = dict1.get(index[1], 0)
        num += 1
        dict1[index[1]] = num
    # 对字典按值进行排序,返回排好后的键组成的列表,原字典不会被改变
    list5 = sorted(dict1, key=lambda x: dict1[x], reverse=True)
    

    django中写入文件除了有上面的方法外,还有下面方法

    from django.core.files.storage import default_storage
    from django.core.files.base import ContentFile
    image = request.FILES.get('images')
    if image.size > 10000 and image.size<2048000:
        path = default_storage.save('User/static/User/images/'+image.name,ContentFile(image.read()))
        tmp_file = os.path.join(settings.MEDIA_ROOT, path)
    

    相关文章

      网友评论

          本文标题:django中文件上传与图片处理

          本文链接:https://www.haomeiwen.com/subject/tgvgbqtx.html