Django文件上传权限异常:大于2MB文件权限受限为-rw-------
解决Django上传文件大小不同导致权限不一致的问题
这个问题的核心原因在于Django处理小文件和大文件的上传逻辑存在差异:
- 当文件小于阈值(你这里是2MB,对应Django默认配置
FILE_UPLOAD_MAX_MEMORY_SIZE,默认值是2.5MB)时,Django会把文件暂存在内存中,再直接写入目标目录media/contracts/...。此时文件权限继承自Django进程的umask设置,所以呈现为-rwxrwxr-x(对应umask 002)。 - 当文件超过这个阈值时,Django会先将文件写入系统临时目录(比如
/tmp),再把文件移动到目标路径。而系统临时目录的默认权限通常是-rw-------(对应umask 077),文件移动时会保留原临时文件的权限,最终就出现了权限不一致的情况。
下面给你几个可行的解决方案:
方案1:自定义文件存储类,强制指定文件权限
这是最稳妥的解决方式,直接在文件保存阶段统一设置权限。创建一个自定义存储类,继承Django默认的FileSystemStorage并重写_save方法:
# 在你的app目录下新建storage.py文件 from django.core.files.storage import FileSystemStorage import os class CustomFileSystemStorage(FileSystemStorage): def _save(self, name, content): # 先执行父类的保存逻辑 file_path = super()._save(name, content) # 设置你需要的文件权限,比如-rwxrwxr-x对应0o775,-rw-rw-r--对应0o664 os.chmod(file_path, 0o775) return file_path
然后在settings.py中配置使用这个自定义存储类:
DEFAULT_FILE_STORAGE = '你的app名称.storage.CustomFileSystemStorage'
方案2:修改Django进程的umask
如果你的Django是通过uWSGI、Gunicorn这类服务启动的,可以在启动脚本中设置umask,让系统临时目录生成的文件权限符合预期。比如在启动命令前添加umask 002:
umask 002 && gunicorn 你的项目名.wsgi:application
这样临时文件的权限会变成-rwxrwxr-x,移动到目标目录后也会保留这个权限。注意这个方法会影响整个Django进程的所有文件操作,需要确认是否符合你的整体需求。
方案3:调整Django的上传内存阈值
把FILE_UPLOAD_MAX_MEMORY_SIZE调大,让所有上传文件都走内存写入的逻辑(不推荐用于大文件场景,会占用过多服务器内存)。在settings.py中修改:
# 设置为你需要的最大内存存储大小,比如10MB FILE_UPLOAD_MAX_MEMORY_SIZE = 10 * 1024 * 1024
这个方法仅适合上传文件普遍偏小的场景,否则会导致服务器内存占用过高。
额外提示
如果你用Nginx代理静态文件,还要确保Nginx的运行用户拥有读取这些上传文件的权限,避免出现403错误。比如可以将Nginx用户加入到Django进程所在的用户组中。
内容的提问来源于stack exchange,提问作者Eddwin Paz
相关产品推荐
相关产品推荐

