OSError on uploading files in Django
While trying to send form with image field in it I'm getting :
Exception Type: OSError at /user/register/
Exception Value: (13, 'Permission denied')
Of course first thing I've checked were the permissions to my folders, and just in case set them to 777 on the whole path from '/'. Still nothing. So I've tried adding parameters to settings, which now are set like this :
ADMIN_MEDIA_PREFIX
'/site_media/admin/'
CACHE_BACKEND
'locmem://'
DEFAULT_CHARSET
'utf-8'
DEFAULT_CONTENT_TYPE
'text/html'
DEFAULT_FILE_STORAGE
'django.core.files.storage.FileSystemStorage'
FILE_CHARSET
'utf-8'
FILE_UPLOAD_HANDLERS
('django.core.files.uploadhandler.MemoryFileUploadHandler', 'django.core.files.uploadhandler.TemporaryFileUploadHandler')
FILE_UPLOAD_MAX_MEMORY_SIZE
2621440
FILE_UPLOAD_PERMISSIONS
777
FILE_UPLOAD_TEMP_DIR
None
FS_ROOT
'/home/rails/fandrive'
MEDIA_ROOT
'/home/fandrive/www/fandrive/site_media'
MEDIA_URL
'/site_media/'
PROJECT_PATH
'/home/rails/fandrive'
SESSION_FILE_PATH
None
Request.META :
CONTENT_LENGTH
'8249'
CONTENT_TYPE
'multipart/form-data; boundary=---------------------------26681719213985'
DOCUMENT_ROOT
'/home/rails/fandrive/public'
HTTP_ACCEPT
'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
HTTP_ACCEPT_CHARSET
'ISO-8859-1,utf-8;q=0.7,*;q=0.7'
HTTP_ACCEPT_ENCODING
'gzip,deflate'
HTTP_ACCEPT_LANGUAGE
'en-us,en;q=0.5'
HTTP_CONNECTION
'keep-alive'
HTTP_CONTENT_LENGTH
'8249'
HTTP_CONTENT_TYPE
'multipart/form-data; boundary=---------------------------26681719213985'
HTTP_HOST
'example.com'
HTTP_KEEP_ALIVE
'115'
HTTP_REFERER
'http://example.com/user/register/'
HTTP_USER_AGENT
'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.6) Gecko/20100625 Firefox/3.6.6'
PATH_INFO
u'/user/register/'
QUERY_STRING
''
REMOTE_PORT
'52869'
REQUEST_METHOD
'POST'
REQUEST_URI
'/user/register/'
SCRIPT_NAME
u''
SERVER_PROTOCOL
'HTTP/1.1'
SERVER_SOFTWARE
'Apache'
_
'_'
wsgi.errors
<open file '<stderr>', mode 'w' at 0x7f2a6026f140>
wsgi.input
<socket._fileobject object at 0x7f2a5cbc4848>
wsgi.multiprocess
True
wsgi.multithread
False
wsgi.run_once
True
wsgi.url_scheme
'http'
wsgi.version
(1, 0)
And finally my traceback :
Traceback:
File "/home/rails/fandrive/site-packages/django/core/handlers/base.py" in get_response
92. response = callback(request, *callback_args, **callback_kwargs)
File "/home/rails/fandrive/registration/views.py" in register
47. new_user = backend.register(request, **form.cleaned_data)
File "/home/rails/fandrive/registration/backends/default/__init__.py" in register
23. request=request)
File "/home/rails/fandrive/site-packages/django/dispatch/dispatcher.py" in send
166. response = receiver(signal=self, sender=sender, **named)
File "/home/rails/fandrive/regbackend.py" in user_created
39. data.save()
File "/home/rails/fandrive/site-packages/django/db/models/base.py" in save
410. self.save_base(force_insert=force_insert, force_update=force_update)
File "/home/rails/fandrive/site-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 "/home/rails/fandrive/site-packages/django/db开发者_Python百科/models/fields/files.py" in pre_save
252. file.save(file.name, file, save=False)
File "/home/rails/fandrive/site-packages/django/db/models/fields/files.py" in save
91. self.name = self.storage.save(name, content)
File "/home/rails/fandrive/site-packages/django/core/files/storage.py" in save
47. name = self._save(name, content)
File "/home/rails/fandrive/site-packages/django/core/files/storage.py" in _save
146. os.makedirs(directory)
File "/bin/python-2.6.1/lib/python2.6/os.py" in makedirs
150. makedirs(head, mode)
File "/bin/python-2.6.1/lib/python2.6/os.py" in makedirs
150. makedirs(head, mode)
File "/bin/python-2.6.1/lib/python2.6/os.py" in makedirs
150. makedirs(head, mode)
File "/bin/python-2.6.1/lib/python2.6/os.py" in makedirs
150. makedirs(head, mode)
File "/bin/python-2.6.1/lib/python2.6/os.py" in makedirs
150. makedirs(head, mode)
File "/bin/python-2.6.1/lib/python2.6/os.py" in makedirs
157. mkdir(name, mode)
Any ideas what more should I check ?
UPDATE : My model
class UserProfile(InheritedProfile):
def upload_path(self, field_attname):
filename = hashlib.md5(field_attname).hexdigest()[:4] + "_" + field_attname
return "uploads/users/%s" % (filename,)
user = models.ForeignKey(User, unique=True, related_name='profile')
image = models.ImageField(upload_to=upload_path, verbose_name="Image", blank=True, null=True)
I have already created 'uploads/users' folder so why is it trying to create a folder - not just a file ?
The apache use that runs your django application does not have the permission to create the folder/file in your media directory.
A quick temporary fix would be to
Go to your media folder:
/home/fandrive/www/fandrive/site_media
and type:
sudo chmod -R a+w
which makes your folder writeable by all users.
This approach may not be secure. To make it secure, you can change the ownership of the folder to that user, or create a group and assign the permissions to that group.
精彩评论