Django app, how to download all files asociated a project?

39 Views Asked by At

I'm trying to create a definition in my view.py file to download all files associated with a project. This time I'm using the python ZipFile package to zip all the files, but I'm having a lot of trouble finding the right code

My Models

class File(models.Model):
    project = models.ForeignKey(Project, on_delete=models.CASCADE)
    project_slug = AutoSlugField(populate_from='project', always_update=True)
    pub_date = models.DateTimeField(auto_now_add=True)

    def directory_path(instance, filename):
        return 'files_project/project_{0}/{1}'.format(instance.project_slug, filename)

    upload = models.FileField(upload_to=directory_path)

My view

def DownloadAllFilebyProject(request, id):
    project = Project.objects.get(id=id)
    files = project.file_set.all()
    zf = zipfile.ZipFile(os.path.join(settings.MEDIA_ROOT, 'files_project/project_{0}/'.format(project.slug), 'allfile.zip'), 'w')
    for file in files:
        zf.writestr(os.path.join(settings.MEDIA_ROOT, 'files_project/project_{0}/'.format(project.slug)), file)
    zf.close()

    return HttpResponse(print(zf))

My Template

<a href="{% url 'apppro:DownloadAllFilebyProject' project.id  %}" class="btn btn-warning float-right" method="get"> descargar todos los archivos</a>

The error

TypeError at /downloadallzipfiles/13
object of type 'File' has no len(
1

There are 1 best solutions below

0
Drennos On

The solution was to change the zip package from zipfile to shutil

def DownloadAllFilebyProject(request, id):
    project = Project.objects.get(id=id)
    zip_filename = os.path.join(settings.MEDIA_ROOT, 'files_project/project_{0}/'.format(project.slug), 'allfile_{0}.zip'.format(project.slug))
    dir_name = os.path.join(settings.MEDIA_ROOT, 'files_project/project_{0}/'.format(project.slug))
    if os.path.exists(zip_filename):
        os.remove(zip_filename)
    zip = shutil.make_archive(zip_filename, 'zip', dir_name)

    if os.path.exists(zip):
        with open(zip, 'rb') as fh:
            response = HttpResponse(fh.read(), content_type="application/vnd.ms-excel")
            response['Content-Disposition'] = 'inline; filename=' + os.path.basename(zip)
            return response
    raise Http404