简体   繁体   中英

Django - generate Zip file and serve (in memory)

I'm trying to serve a zip file that contains Django objects images.

The problem is that even if it returns the Zip file, it is corrupted.

NOTE: I can't use absolute paths to files since I use remote storage.

model method that should generate in memory zip

def generate_images_zip(self) -> bytes:
    content = BytesIO()
    zipObj = ZipFile(content, 'w')
    for image_fieldname in self.images_fieldnames():
        image = getattr(self, image_fieldname)
        if image:
            zipObj.writestr(image.name, image.read())
    return content.getvalue()

ViewSet action

@action(methods=['get'], detail=True, url_path='download-images')
def download_images(self, request, pk=None) -> HttpResponse:
    product = self.get_object()
    zipfile = product.generate_images_zip()
    response = HttpResponse(zipfile, content_type='application/zip')
    response['Content-Disposition'] = 'attachment; filename=images.zip'
    return response

When I try to open the downloaded Zip file, it says it's corrupted.

Do you know how to make it work?

You make the very rookie mistake of not calling close / closing the file ( ZipFile here) after opening it, best use the ZipFile as a context manager:

def generate_images_zip(self) -> bytes:
    content = BytesIO()
    with ZipFile(content, 'w') as zipObj:
        for image_fieldname in self.images_fieldnames():
            image = getattr(self, image_fieldname)
            if image:
                zipObj.writestr(image.name, image.read())
    return content.getvalue()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM