上传文件时Django的权限被拒绝错误

Posted

技术标签:

【中文标题】上传文件时Django的权限被拒绝错误【英文标题】:Permission Denied error with Django while uploading a file 【发布时间】:2010-12-13 12:54:12 【问题描述】:

我目前定义了一个简单的模型,具有使用django thumbnails 插件的照片上传功能。

但是当我尝试上传时,它给了我以下错误:

OSError at /admin/products/photo/add/

(13, 'Permission denied')

现在,我知道这似乎是一个权限问题,所以我检查的第一件事是目录的权限并将其更改为 777(只是为了测试),重新启动服务器和 fcgi,它仍然给出错误。

追溯

Traceback: File "/usr/lib/python2.6/dist-packages/django/core/handlers/base.py" in get_response
  92.                 response = callback(request, *callback_args,
**callback_kwargs) File "/usr/lib/python2.6/dist-packages/django/contrib/admin/options.py" in wrapper
  226.                 return self.admin_site.admin_view(view)(*args,
**kwargs) File "/usr/lib/python2.6/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func
  44.         response = view_func(request, *args, **kwargs) File "/usr/lib/python2.6/dist-packages/django/contrib/admin/sites.py" in inner
  186.             return view(request, *args, **kwargs) File "/usr/lib/python2.6/dist-packages/django/db/transaction.py" in _commit_on_success
  240.                 res = func(*args, **kw) File "/usr/lib/python2.6/dist-packages/django/contrib/admin/options.py" in add_view
  734.                 self.save_model(request, new_object, form, change=False) File "/usr/lib/python2.6/dist-packages/django/contrib/admin/options.py" in save_model
  557.         obj.save() File "/usr/lib/python2.6/dist-packages/django/db/models/base.py" in save
  410.         self.save_base(force_insert=force_insert, force_update=force_update) File "/usr/lib/python2.6/dist-packages/django/db/models/base.py" in save_base
  483.                     values = [(f, f.get_db_prep_save(raw and getattr(self, f.attname) or f.pre_save(self, True))) for f in meta.local_fields if not isinstance(f, AutoField)] File "/usr/lib/python2.6/dist-packages/django/db/models/fields/files.py" in pre_save
  252.             file.save(file.name, file, save=False) File "/var/www/django_projects/gang/../gang/products/thumbs.py" in save
  84.         super(ImageWithThumbsFieldFile, self).save(name, content, save) File "/usr/lib/python2.6/dist-packages/django/db/models/fields/files.py" in save
  91.         self.name = self.storage.save(name, content) File "/usr/lib/python2.6/dist-packages/django/core/files/storage.py" in save
  47.         name = self._save(name, content) File "/usr/lib/python2.6/dist-packages/django/core/files/storage.py" in _save
  146.             os.makedirs(directory) File "/usr/lib/python2.6/os.py" in makedirs
  150.             makedirs(head, mode) File "/usr/lib/python2.6/os.py" in makedirs
  150.             makedirs(head, mode) File "/usr/lib/python2.6/os.py" in makedirs
  150.             makedirs(head, mode) File "/usr/lib/python2.6/os.py" in makedirs
  157.     mkdir(name, mode)

Exception Type: OSError at /admin/products/photo/add/ Exception Value: (13, 'Permission denied')

运行 FCGI 守护程序的用户肯定有权读取和写入该目录。

来自 settings.py

MEDIA_ROOT = '/var/www/sites/gang/http/media/'
MEDIA_ROOT_URL = '/media/'

【问题讨论】:

【参考方案1】:

尝试检查从 / 开始的路径中每个目录的权限。只是一个想法。

【讨论】:

嗨,彼得,更改根目录的权限似乎有点不安全? 呃,我相信我说的是“检查”,而不是“改变”……差别很大。我见过以下情况:您的 DOCROOT 位于 /a/b/c/d。 'd' 是 777(通常是绝望),'a' 和 'b' 是 755(正常),但 'c' 是 700(或类似的),这几乎结束了聚会。你一直在玩“d”,但问题出在“c”(或其他)。【参考方案2】:
mkdir(name, mode)

Exception Type: OSError at /admin/products/photo/add/

但您的应用程序部署在

/var/www/django_projects/gangr/../gangr/

您是否将目录路径设置为绝对路径“/admin/products/photo/add/”,而不是像“admin/products/photo/add/”这样的相对路径?

检查 settings.py 文件中的 MEDIA_ROOT 和 MEDIA_URL。

http://docs.djangoproject.com/en/dev/ref/settings/#media-root

【讨论】:

嗨,我的应用程序实际上部署在:/var/www/django_projects/gangr/products/ 不知道为什么会这样说 /.../gangr 但是我确实有一个 MEDIA_ROOT 设置(它指向lightttpd 使用的 http 即 '.../http/media' 和 MEDIA_ROOT_URL 是 '/media/'【参考方案3】:

我刚刚遇到了同样的问题。如果您使用 Apache 作为服务器进行托管,则找到了解决方案。例如,如果我的设置是:

MEDIA_ROOT = '/var/www/media/geekingreen'

那么我只需要递归地为该文件夹授予正确的权限,以确保任何子文件夹也具有相同的权限。 apache 的默认组是 www-data,因此要授予我的 django 应用程序权限,我将运行这些命令。

cd /var/www/media
chgrp -R www-data geekingreen/
chmod -R g+w geekingreen/

chgrp -R www-data geekingreen/ 命令将 geekingreen 目录和任何子目录更改为包含 www-data 组。 chmod -R g+w geekingreen/ 命令将组对现在属于 www-data 的所有这些文件夹的权限更改为现在具有写入权限。显然需要上传。 希望这可以帮助任何可能遇到类似问题的人。

【讨论】:

这对我来说已经够干净了+1 @geekingreen 是否可以在开发服务器上做同样的事情? 知道了 :) 你必须授予运行“runserver”的用户权限【参考方案4】:

以防万一您在运行开发服务器时遇到这种情况。 我像这样以 root 身份运行开发服务器:sudo python manage.py runserver 0.0.0.0:80,以便在同一 LAN 网络中使用 iPad 测试站点。 在该会话中生成的缓存文件属于 root。因此,当我第二天以非 root 身份运行项目时,我得到了权限被拒绝错误。

【讨论】:

【参考方案5】:

为了让您的应用能够上传媒体文件,您需要更改权限和所有者设置。 apache 的默认组是 www-data,因此要授予 Django 应用程序权限,您应该运行这些命令。

sudo groupadd www-data
sudo adduser www-data www-data
sudo chgrp -R www-data media
sudo chown -R www-data media
sudo chmod -R 770 media

一步一步,这将创建一个名为“www-data”的新用户组,将用户 www-data 添加到该组,将媒体的用户组更改为“www-data”,最后更改所有者权限到 770,它允许所有者 (root) 和所有者组 (www-data) 的读取、写入和执行权限,而其他任何人都没有访问权限。因为 www-data 已添加到 www-data 组,所以 www-data 现在可以读写了。

【讨论】:

以上是关于上传文件时Django的权限被拒绝错误的主要内容,如果未能解决你的问题,请参考以下文章

nginx 500 错误,tmp 文件夹的权限被拒绝

文件传输权限被拒绝

上传问题(权限被拒绝)

Apache上传文件/tmp权限被拒绝

Apache spark:上传到作业暂存目录的文件的权限被拒绝

iis上部署asp.net网站,访问上传的文件时被拒绝