How to download uploaded directory as a zip file from django admin?

1.8k Views Asked by At

I have uploaded directory using django and JavaScript. Now I am trying to download this directory from django admin. For this purpose I have followed this link click here. When I have uploaded directory in django, the admin created the following table. File name indicates the uploaded folder name.

enter image description here

If I click on the file name, it shows me following error. I want to download this directory as a zip file from django admin. Can anyone please help me with this?

enter image description here

Here is my model.py:

class Prearchive(models.Model):
    file = models.FileField(upload_to='media/', null=True) 
    file_name = models.CharField(max_length=500,primary_key=True)    
    file_id = models.ForeignKey(CreateScan, on_delete=models.CASCADE,default=1) 

    def _str_(self):
        return self.file_name 

admin.py:

from django.contrib import admin
from .models import CreateScan, Prearchive

# Register your models here.

class PrearchiveAdmin(admin.ModelAdmin):
    model=Prearchive
    list_display = ('file_name','file_id','file_link')
    def file_link(self, obj):
        if obj.file:
            return "<a href='%s' download>Download</a>" % (obj.file.url,)
        else:
            return "No attachment"
    file_link.allow_tags = True
    file_link.short_description = 'File Download'

admin.site.register(Prearchive , PrearchiveAdmin)

view.py:

@login_required
def downloadScanView(request,url):
    print('url',url)
    response = HttpResponse(content_type='application/zip')
    file_path = os.path.join(settings.MEDIA_ROOT, url)
    zip_download = ZipFile(response, 'w',ZIP_DEFLATED)
    if os.path.exists(file_path):
        for root, dir, files in os.walk(file_path):
            print('r = ',root)
            for file in files:
                zip_download.write(os.path.join(root,file))
        response['Content-Disposition'] = 'attachment; filename={}'.format(os.path.basename(url)+'.zip')
        return response
1

There are 1 best solutions below

2
55abhilash On

Create a view to download the file, and add urls.py entry for /media to this view.

views.py

def filedownload(request, filename):
    zf = zipfile.ZipFile('download.zip', 'w', zipfile.ZIP_DEFLATED)
    zf.write("media/" + filename)
    response = HttpResponse(zf, content_type='application/force-download')
    response['Content-Disposition'] = 'attachment; filename="download.zip"'
    return response

Main urls.py

path('media/', include('your_app.urls')

App urls.py

path("<filename>/", views.filezip, name="filedownload")