【问题标题】:Zipping files in Django view and serving them在 Django 视图中压缩文件并提供服务
【发布时间】:2012-03-10 06:47:31
【问题描述】:

首先我想说,我知道从 django 提供文件是不好的,但我的情况只能由 django 处理,所以我选择它来提供压缩文件。在我的 models.py 中,我有一个模型

class Documents(models.Model):
    filename = models.CharField(max_length=100)
    document = models.FileField(upload_to='docs')
    allowedGroup = models.ManyToManyField(Group)

因此,当普通用户登录时,它将根据他/她的组显示他具有权限的文档。我希望用户能够一次下载多个文档(文件)。所以我所做的是添加了这个处理程序,用于将多个文件下载为 zip 文件:

我用这个Django Snippet 来创建这个视图

  def Download_selected_document(self, request, queryset):  

    if len(queryset)>1:

        temp = tempfile.TemporaryFile()
        archive = zipfile.ZipFile(temp, 'w', zipfile.ZIP_DEFLATED)
        for i in queryset:
            ##Reading the file content
            content = open(settings.MEDIA_ROOT+str(i.document),'rb').read()
            ##name is name of file like "abc.docx"
            name = str(queryset[0].document)[10:]
            ##At this like it gives me error
            archive.write(content,name)

        archive.close()
        wrapper = FileWrapper(temp)
        response = HttpResponse(wrapper, content_type='application/zip')
        response['Content-Disposition'] = 'attachment; filename=test.zip'
        response['Content-Length'] = temp.tell()
        temp.seek(0)
        return response

    else:
        self.message_user(request, "You must select multiple documents for downloading.")

我得到的错误是:必须是没有 NULL 字节的编码字符串,而不是 str

Traceback:
File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
  111.                         response = callback(request, *callback_args, **callback_kwargs)
File "C:\Python27\lib\site-packages\django\contrib\admin\options.py" in wrapper
  307.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  93.                     response = view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
  79.         response = view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\contrib\admin\sites.py" in inner
  197.             return view(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py" in _wrapper
  28.             return bound_func(*args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  93.                     response = view_func(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django\utils\decorators.py" in bound_func
  24.                 return func(self, *args2, **kwargs2)
File "C:\Python27\lib\site-packages\django\contrib\admin\options.py" in changelist_view
  1079.                 response = self.response_action(request, queryset=cl.get_query_set())
File "C:\Python27\lib\site-packages\django\contrib\admin\options.py" in response_action
  836.             response = func(self, request, queryset)
File "C:\Documents and Settings\Anshul\Desktop\online.in\online\..\online\assessment\admin.py" in Download_selected_document
  82.             archive.write(content,name)
File "C:\Python27\lib\zipfile.py" in write
  1031.         st = os.stat(filename)

Exception Type: TypeError at /admin/assessment/userdocuments/
Exception Value: must be encoded string without NULL bytes, not str

我不知道我应该如何解决这个问题。请帮助

【问题讨论】:

    标签: python django django-views zipfile


    【解决方案1】:

    使用

    zipfile.ZipFile().writestr(archived_name, content_to_be_archived)
    

    而不是

    zipfile.ZipFile().write(filename_to_load_content_from, archived_name=None) 
    

    所以可以快速解决

    archive.write(content,name) => archive.writestr(name, content)
    

    此外,您可能需要检查

    • 如果压缩文件的大小通常很小,则使用 StringIO 而不是 tempfile
    • 由于 HttpResponse 对象是类文件对象,您可以直接压缩到它
    • 在 nginx 中使用 XSendfile 或 X-Accel-Redirect 来帮助传输响应的文件,而不是依赖 Django 本身

    【讨论】:

    • 太棒了............它对我有用,但它应该是 archive.write(content,name) => archive.writestr(name, content)
    • @anks 啊哈,是的。这里太多的 WRITE 也让我感到困惑 =p 已修复
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-11
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    • 2010-10-31
    • 2015-07-09
    • 1970-01-01
    相关资源
    最近更新 更多