在Django中设置生成的zip文件的正确权限

7 投票
2 回答
2047 浏览
提问于 2025-04-16 16:45

我正在使用Django和Python2.6来生成一个包含自定义Django模板的压缩文件,让每个用户都能下载这个定制的zip文件。目前,views.py里的代码是这样的:

def download(request):
    response = HttpResponse(mimetype='application/x-zip-compressed')
    response['Content-Disposition'] = 'attachment; filename=download.zip'

    myzip = zipfile.ZipFile(response, 'w')

    now = datetime.datetime.now()
    zipInfo = zipfile.ZipInfo('thefile.txt', (now.year, now.month, now.day, now.hour, now.minute, now.second))
    myzip.writestr(zipInfo, render_to_string('template.txt', locals(), context_instance=RequestContext(request)))
    myzip.close()

    return response

大部分情况下,这个功能都能正常工作:压缩文件(在这个例子中只包含一个txt文件)可以正确下载,我也能解压缩内容。不过,唯一的问题是,生成的文件对我的默认用户来说既没有读取权限,也没有写入权限,网站用户也一样。

我该如何在下载之前更改自动生成文件的权限呢?

更新

我试过使用os.chmodos.fchmod,正如Mike建议的那样,但这要么需要一个路径名(我没有),要么会报错(对于fchmod):

ZipFile实例没有属性'__trunc__'

我想,一个选择是先保存压缩文件,设置好权限,然后再允许下载,但这似乎有点过于复杂——应该有更简单的方法来解决这个问题。有人有什么建议或想法吗?

更新2

看来这个问题只出现在Unix系统上,因为在Windows和(显然)OS X上都能正常工作。我找到一个类似的讨论,在这里。据我所知,这可能与writestr方法有关。我该如何设置通过writestr方法添加到压缩文件中的文件的权限呢?

2 个回答

0

在Unix系统中,每个进程都有默认的文件权限设置。你可以了解一下:
umask(用户文件创建权限掩码)
可以尝试为Django进程设置这个权限。

4

我觉得这个问题出在你用来解压缩zip文件的工具上。权限看起来没问题:

zk@fool:~/Downloads% ls -l | grep thefile
-rwxr-xr-x@  1 zk  staff           9 May  3 06:37 thefile.txt*

我在mac的Archive Utility、Windows自带的zip浏览器和7-zip上都能正常工作。检查生成的zip文件发现,里面的文件根本没有任何属性。所以我怀疑你用来解压的工具可能把权限设置错了。

你可以试试设置ZipInfo.external_attr:

zipInfo.external_attr = 0777 << 16L # set permissions on file

这似乎能在Linux系统上修复权限问题:

zk@arch:~% ls -l | grep thefile
-rwxrwxrwx  1 zk     9 May  3 07:06 thefile.txt*

撰写回答