Django下载S3文件并包含在zip中

时间:2019-11-26 15:50:45

标签: django amazon-s3 django-storage

我有这段代码可以将文件添加到Django中的zip文件中。当介质是本地介质时工作正常,但是使用s3存储桶时出现以下错误:

FileNotFoundError at /en/admin/certification/application/

[Errno 2] No such file or directory: 'https://bucket-name.s3.amazonaws.com/media/application_files/name_of_the_pdf.pdf'

代码如下:

    filename = settings.MEDIA_ROOT  + q.user.username + '-' + q.certification.standard.name + '-' + q.certification.name
    zf = zipfile.ZipFile(byte, "w")
    zipped_files = []
    zip_filename = filename + '.zip'
    csv_filename = filename + '.csv'
    with open(csv_filename, 'w') as csvfile:
        filewriter = csv.writer(csvfile, delimiter=',', quoting=csv.QUOTE_MINIMAL)
        for answer in q.answer_set.all():
            if answer.question.question_type in ['file', 'files']: 
                if answer.f :
                    if 'RDS_HOSTNAME' in os.environ: 
                        res = answer.f.url
                    else: res = settings.BASE_DIR + answer.f.url
                    zf.write(res)
            elif answer.question.question_type == 'text' : res = answer.text
            else : res = answer.checkbox.name

            filewriter.writerow([answer.question.question, res])
    zf.write(csv_filename)
    zf.close()

    resp = HttpResponse(
        byte.getvalue(), content_type="application/x-zip-compressed")
    resp['Content-Disposition'] = 'attachment; filename=%s' % zip_filename

和追溯:

跟踪:

File "/opt/python/run/venv/local/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/opt/python/run/venv/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "/opt/python/run/venv/local/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/opt/python/run/venv/local/lib/python3.6/site-packages/django/contrib/admin/options.py" in wrapper
  604.                 return self.admin_site.admin_view(view)(*args, **kwargs)

File "/opt/python/run/venv/local/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)

File "/opt/python/run/venv/local/lib/python3.6/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
  44.         response = view_func(request, *args, **kwargs)

File "/opt/python/run/venv/local/lib/python3.6/site-packages/django/contrib/admin/sites.py" in inner
  223.             return view(request, *args, **kwargs)

File "/opt/python/run/venv/local/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapper
  45.         return bound_method(*args, **kwargs)

File "/opt/python/run/venv/local/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)

File "/opt/python/run/venv/local/lib/python3.6/site-packages/django/contrib/admin/options.py" in changelist_view
  1701.                 response = self.response_action(request, queryset=cl.get_queryset(request))

File "/opt/python/run/venv/local/lib/python3.6/site-packages/django/contrib/admin/options.py" in response_action
  1400.             response = func(self, request, queryset)

File "/opt/python/current/app/certification/admin_actions.py" in download_application
  31.                         zf.write(res)

File "/usr/lib64/python3.6/zipfile.py" in write
  1617.         zinfo = ZipInfo.from_file(filename, arcname)

File "/usr/lib64/python3.6/zipfile.py" in from_file
  507.         st = os.stat(filename)

Exception Type: FileNotFoundError at /en/admin/certification/application/
Exception Value: [Errno 2] No such file or directory: 'https://bucket-name.s3.amazonaws.com/media/application_files/name_of_the_pdf.pdf'

我已将存储桶和文件名更改为示例。

我怎么了?

1 个答案:

答案 0 :(得分:0)

这是我的解决方法:

                    if answer.f :
                        if 'RDS_HOSTNAME' in os.environ: 
                            res = answer.f.url
                            response = requests.get(answer.f.url)
                            zf.writestr(answer.f.url, response.content)
                        else: 
                            res = settings.BASE_DIR + answer.f.url
                            zf.write(res)