在Django中设置生成的zip文件的正确权限
我正在使用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.chmod
和os.fchmod
,正如Mike建议的那样,但这要么需要一个路径名(我没有),要么会报错(对于fchmod
):
ZipFile实例没有属性'__trunc__'
我想,一个选择是先保存压缩文件,设置好权限,然后再允许下载,但这似乎有点过于复杂——应该有更简单的方法来解决这个问题。有人有什么建议或想法吗?
更新2:
看来这个问题只出现在Unix系统上,因为在Windows和(显然)OS X上都能正常工作。我找到一个类似的讨论,在这里。据我所知,这可能与writestr
方法有关。我该如何设置通过writestr
方法添加到压缩文件中的文件的权限呢?
2 个回答
在Unix系统中,每个进程都有默认的文件权限设置。你可以了解一下:
umask(用户文件创建权限掩码)
可以尝试为Django进程设置这个权限。
我觉得这个问题出在你用来解压缩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*