2

I want to download one directory from my server on button click. The directory should be downloaded in zip format. I am using Django and Python. I tried this earlier with the same code but it was on Python2 venv. The same code on Python3 venv gives utf-8 codec can't decode byte error. The zip of the directory is created successfully but when i press the download button on my website it throws me above error.

@login_required
def logs_folder_index(request):
    user = request.user
    if not is_moderator(user):
        raise Http404("You are not allowed to see this page.")
    else:
        if os.path.exists('Experiments.zip'):
            os.remove('Experiments.zip')
        zipf = zipfile.ZipFile('Experiments.zip','w',zipfile.ZIP_DEFLATED)
        path = settings.BASE_DIR + '/experiments/'
        zipdir(path,zipf)
        zipf.close()
        zip_file = open('Experiments.zip','r')
        response = HttpResponse(zip_file, 
                content_type='application/force-download')
        response['Content-Disposition'] = 'attachment; filename="{0}"'\
                                        .format(Experiments.zip)
        return response

Can someone please help me with this problem.

Akash Chavan
  • 77
  • 2
  • 9

1 Answers1

2

Your read the file as a text stream (since the mode is 'r', and not 'rb'). Since zips are typically not encoded in UTF-8 (or any text codec in general), it is likely to eventually reach a byte sequence that can not be decoded (or will be decoded non-sensical), you thus should read it as a binary file:

@login_required
def logs_folder_index(request):
    user = request.user
    if not is_moderator(user):
        raise Http404("You are not allowed to see this page.")
    elif os.path.exists('Experiments.zip'):
        os.remove('Experiments.zip')
    with zipfile.ZipFile('Experiments.zip','w',zipfile.ZIP_DEFLATED) as zipf:
        path = settings.BASE_DIR + '/experiments/'
        zipdir(path,zipf)
    with open('Experiments.zip','rb') as stream:
        response = HttpResponse(stream, content_type='application/force-download')
        response['Content-Disposition'] = 'attachment; filename="Experiments.zip"'
        return response
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555