首页 > 解决方案 > 使用 zip_file 从 DJango 视图返回 zip:找不到简单的方法

问题描述

我想遍历一个文件夹的所有文件来制作一个 zip 文件夹

在制作 zip 之前,我需要过滤文件中的行我已经找到了一种方法,但似乎“hack”所以我想知道是否有一个好的解决方案

对于测试,我的文件夹中有 2 个文件:file1.csv 和 file2.csv

原始文件1.csv

field1,field2,filed3
CI-S1-001,1,test1
CI-S1-002,1,test2

原始文件2.csv

field1,field2,filed3
ZA-S1-001,1,test3
ZA-S2-002,1,test4

filters_export 视图函数将遍历 2 个文件并根据第一个字段过滤行

由于用户在“S1”和“S3”上具有权限,如果 zip 文件和 zip 文件夹将包含 2 个文件,则 file1.csv 的 2 行和只有第一行 file2.csv 将被返回并写入

压缩文件1.csv

field1,field2,filed3
CI-S1-001,1,test1
CI-S1-002,1,test2

压缩文件2.csv

field1,field2,filed3
ZA-S1-001,1,test3
def filtered_export(request):
    
    # site list available for user
    sites = ['S1','S3']

    ...
    # retrieve the list of all files in study directory excluding 'archives' directory
    listOfFiles = getListOfFiles(path)
    
    # Create zip
    buffer = io.BytesIO()
    zip_file = zipfile.ZipFile(buffer, 'w')
    
    for file in listOfFiles:
        records = []
        # read the files 
        with open(path + file, newline='', encoding="utf8") as csvfile:
            has_header = csv.Sniffer().has_header(csvfile.read())   
            csvfile.seek(0)
            spamreader = csv.reader(csvfile, delimiter=',', quotechar='|')
            csv_headings = ','.join(next(spamreader))
            
            for row in spamreader:
                for site in sites:
                    if site in row[0]: # filter on substring of the firts field of csv file
                        records.append(','.join(row))

        zip_file.writestr(file, csv_headings+'\n'+'\n'.join(records))
                       
                
    zip_file.close()
        
   
    # Return zip
    response = HttpResponse(buffer.getvalue())
    response['Content-Type'] = 'application/x-zip-compressed'
    response['Content-Disposition'] = 'attachment; filename='+study+'.zip'

    return response


标签: pythondjangozipfile

解决方案


推荐阅读