OSError at /blog/create [Errno 13] Permission denied: '/static' during image upload in Django
OSError at /blog/create [Errno 13] Permission denied: '/static' during image upload in Django
所以我正在通过构建自己的博客应用程序来练习 Django,但我无法弄清楚为什么在尝试使用 ImageField 上传 header 图像时会出现此错误。我将 wsgi 配置为使用正确的用户,如下所示。并且我确保用户在静态目录中具有完全权限。关于这个问题,我在这里看到了一些类似的帖子,但 none 已经为我修复了它。
这是回溯:
Environment:
Request Method: POST
Request URL: http://example.com/blog/create
Django Version: 1.8.4
Python Version: 2.7.6
Installed Applications:
('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'app',
'grappelli',
'filebrowser',
'tinymce',
'django.contrib.admin')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware')
Traceback:
File "/var/www/example.com/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/var/www/example.com/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
22. return view_func(request, *args, **kwargs)
File "/var/www/example.com/mysite/app/views.py" in create_post
93. post.save()
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/base.py" in save
734. force_update=force_update, update_fields=update_fields)
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/base.py" in save_base
762. updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/base.py" in _save_table
846. result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/base.py" in _do_insert
885. using=using, raw=raw)
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/manager.py" in manager_method
127. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/query.py" in _insert
920. return query.get_compiler(using=using).execute_sql(return_id)
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
973. for sql, params in self.as_sql():
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in as_sql
931. for obj in self.query.objs
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/fields/files.py" in pre_save
315. file.save(file.name, file, save=False)
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/fields/files.py" in save
94. self.name = self.storage.save(name, content, max_length=self.field.max_length)
File "/var/www/example.com/lib/python2.7/site-packages/django/core/files/storage.py" in save
64. name = self._save(name, content)
File "/var/www/example.com/lib/python2.7/site-packages/django/core/files/storage.py" in _save
223. os.makedirs(directory)
File "/usr/lib/python2.7/os.py" in makedirs
150. makedirs(head, mode)
File "/usr/lib/python2.7/os.py" in makedirs
157. mkdir(name, mode)
Exception Type: OSError at /blog/create
这里是 settings.py:
"""
Django settings for example project.
"""
from os import path
PROJECT_ROOT = path.dirname(path.abspath(path.dirname(__file__)))
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ALLOWED_HOSTS = (
'.example.com',
'.example.com.',
)
ADMINS = (
# ('Your Name', 'your_email@example.com'),
('My Name', 'myemail@gmail.com'),
)
MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '...',
'USER': '...',
'PASSWORD': '...',
'HOST': '...',
'PORT': '3306',
'CONN_MAX_AGE': None
}
}
LOGIN_URL = '/login'
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# On Unix systems, a value of None will cause Django to use the same
# timezone as the operating system.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = 'America/Chicago'
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'
SITE_ID = 1
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True
# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = '/static/media/'
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = '/media/'
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = '/var/www/example.com/mysite/static/'
# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
# Make this unique, and don't share it with anybody.
SECRET_KEY = '...'
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.request',
)
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
# 'django.template.loaders.eggs.Loader',
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
)
#SESSION_COOKIE_SECURE = True
#CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True
X_FRAME_OPTIONS = 'DENY'
ROOT_URLCONF = 'mysite.urls'
# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'example.wsgi.application'
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or
# "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'app',
#'disqus',
'grappelli',
'filebrowser',
'tinymce',
# Uncomment the next line to enable the admin:
'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
)
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
}
}
# Specify the default test runner.
TEST_RUNNER = 'django.test.runner.DiscoverRunner'
TINYMCE_JS_ROOT = '/var/www/example/mysite/static/tiny_mce'
TINYMCE_JS_URL = 'http://54.152.243.113/static/tiny_mce/tiny_mce_src.js'
TINYMCE_COMPRESSOR = True
FILEBROWSER_MEDIA_ROOT = MEDIA_ROOT
FILEBROWSER_MEDIA_URL = MEDIA_URL
FILEBROWSER_DIRECTORY = ''
阿帕奇 mysite.conf:
ServerSignature off
Group varwwwusers
<VirtualHost *:80>
ServerAdmin webmaster@example.com
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/mysite/
ErrorLog /var/www/example.com/logs/error.log
CustomLog /var/www/example.com/logs/access.log combined
Alias /robots.txt /var/www/example.com/mysite/app/static/robots.txt
Alias /favicon.ico /var/www/example.com/mysite/app/static/favicon.ico
Alias /media/ /var/www/example.com/mysite/static/media/
Alias /static/ /var/www/example.com/mysite/static/
<Directory /var/www/example.com/mysite/static>
Require all granted
</Directory>
<Directory /var/www/example.com/mysite/static/media>
Require all granted
</Directory>
<Directory /var/www/example.com/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess example.com user=www-data group=varwwwusers python-path=/var/www/example.com/mysite:/var/www/example.com/lib/python2.7/site-packages
WSGIProcessGroup example.com
WSGIScriptAlias / /var/www/example.com/mysite/example/wsgi.py
</VirtualHost>
最后是 views.py 中似乎发生错误的部分(根据跟踪的 post.save() 调用):
@login_required
def create_post(request):
if request.method == "POST":
form = BlogForm(request.POST,request.FILES)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.publish_date = datetime.now()
post.save()
return HttpResponseRedirect('/blog/page/1')
else:
form = BlogForm()
return render(request, 'app/createblogpost.html', { 'title': 'Blog Poster', 'form': form, })
如果有任何不同,我将在 AWS EC2 免费套餐上托管示例站点并且数据库是 AWS RDS。任何解决这个问题的帮助将不胜感激!如果需要任何进一步的信息,请告诉我。
问题在这里:
MEDIA_ROOT = '/static/media/'
MEDIA_ROOT 应该是绝对路径(的确如此,但它没有指向正确的目录)。它应该是这样的:
MEDIA_ROOT = '/var/www/example.com/mysite/static/media'
所以我正在通过构建自己的博客应用程序来练习 Django,但我无法弄清楚为什么在尝试使用 ImageField 上传 header 图像时会出现此错误。我将 wsgi 配置为使用正确的用户,如下所示。并且我确保用户在静态目录中具有完全权限。关于这个问题,我在这里看到了一些类似的帖子,但 none 已经为我修复了它。
这是回溯:
Environment:
Request Method: POST
Request URL: http://example.com/blog/create
Django Version: 1.8.4
Python Version: 2.7.6
Installed Applications:
('django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'app',
'grappelli',
'filebrowser',
'tinymce',
'django.contrib.admin')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware')
Traceback:
File "/var/www/example.com/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/var/www/example.com/lib/python2.7/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
22. return view_func(request, *args, **kwargs)
File "/var/www/example.com/mysite/app/views.py" in create_post
93. post.save()
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/base.py" in save
734. force_update=force_update, update_fields=update_fields)
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/base.py" in save_base
762. updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/base.py" in _save_table
846. result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/base.py" in _do_insert
885. using=using, raw=raw)
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/manager.py" in manager_method
127. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/query.py" in _insert
920. return query.get_compiler(using=using).execute_sql(return_id)
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
973. for sql, params in self.as_sql():
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in as_sql
931. for obj in self.query.objs
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/fields/files.py" in pre_save
315. file.save(file.name, file, save=False)
File "/var/www/example.com/lib/python2.7/site-packages/django/db/models/fields/files.py" in save
94. self.name = self.storage.save(name, content, max_length=self.field.max_length)
File "/var/www/example.com/lib/python2.7/site-packages/django/core/files/storage.py" in save
64. name = self._save(name, content)
File "/var/www/example.com/lib/python2.7/site-packages/django/core/files/storage.py" in _save
223. os.makedirs(directory)
File "/usr/lib/python2.7/os.py" in makedirs
150. makedirs(head, mode)
File "/usr/lib/python2.7/os.py" in makedirs
157. mkdir(name, mode)
Exception Type: OSError at /blog/create
这里是 settings.py:
"""
Django settings for example project.
"""
from os import path
PROJECT_ROOT = path.dirname(path.abspath(path.dirname(__file__)))
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ALLOWED_HOSTS = (
'.example.com',
'.example.com.',
)
ADMINS = (
# ('Your Name', 'your_email@example.com'),
('My Name', 'myemail@gmail.com'),
)
MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': '...',
'USER': '...',
'PASSWORD': '...',
'HOST': '...',
'PORT': '3306',
'CONN_MAX_AGE': None
}
}
LOGIN_URL = '/login'
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# On Unix systems, a value of None will cause Django to use the same
# timezone as the operating system.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = 'America/Chicago'
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'
SITE_ID = 1
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale.
USE_L10N = True
# If you set this to False, Django will not use timezone-aware datetimes.
USE_TZ = True
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = '/static/media/'
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = '/media/'
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = '/var/www/example.com/mysite/static/'
# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
# Make this unique, and don't share it with anybody.
SECRET_KEY = '...'
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.request',
)
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
# 'django.template.loaders.eggs.Loader',
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
# Uncomment the next line for simple clickjacking protection:
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
)
#SESSION_COOKIE_SECURE = True
#CSRF_COOKIE_SECURE = True
CSRF_COOKIE_HTTPONLY = True
X_FRAME_OPTIONS = 'DENY'
ROOT_URLCONF = 'mysite.urls'
# Python dotted path to the WSGI application used by Django's runserver.
WSGI_APPLICATION = 'example.wsgi.application'
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or
# "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'app',
#'disqus',
'grappelli',
'filebrowser',
'tinymce',
# Uncomment the next line to enable the admin:
'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
# 'django.contrib.admindocs',
)
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error when DEBUG=False.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
}
}
# Specify the default test runner.
TEST_RUNNER = 'django.test.runner.DiscoverRunner'
TINYMCE_JS_ROOT = '/var/www/example/mysite/static/tiny_mce'
TINYMCE_JS_URL = 'http://54.152.243.113/static/tiny_mce/tiny_mce_src.js'
TINYMCE_COMPRESSOR = True
FILEBROWSER_MEDIA_ROOT = MEDIA_ROOT
FILEBROWSER_MEDIA_URL = MEDIA_URL
FILEBROWSER_DIRECTORY = ''
阿帕奇 mysite.conf:
ServerSignature off
Group varwwwusers
<VirtualHost *:80>
ServerAdmin webmaster@example.com
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com/mysite/
ErrorLog /var/www/example.com/logs/error.log
CustomLog /var/www/example.com/logs/access.log combined
Alias /robots.txt /var/www/example.com/mysite/app/static/robots.txt
Alias /favicon.ico /var/www/example.com/mysite/app/static/favicon.ico
Alias /media/ /var/www/example.com/mysite/static/media/
Alias /static/ /var/www/example.com/mysite/static/
<Directory /var/www/example.com/mysite/static>
Require all granted
</Directory>
<Directory /var/www/example.com/mysite/static/media>
Require all granted
</Directory>
<Directory /var/www/example.com/mysite>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
WSGIDaemonProcess example.com user=www-data group=varwwwusers python-path=/var/www/example.com/mysite:/var/www/example.com/lib/python2.7/site-packages
WSGIProcessGroup example.com
WSGIScriptAlias / /var/www/example.com/mysite/example/wsgi.py
</VirtualHost>
最后是 views.py 中似乎发生错误的部分(根据跟踪的 post.save() 调用):
@login_required
def create_post(request):
if request.method == "POST":
form = BlogForm(request.POST,request.FILES)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.publish_date = datetime.now()
post.save()
return HttpResponseRedirect('/blog/page/1')
else:
form = BlogForm()
return render(request, 'app/createblogpost.html', { 'title': 'Blog Poster', 'form': form, })
如果有任何不同,我将在 AWS EC2 免费套餐上托管示例站点并且数据库是 AWS RDS。任何解决这个问题的帮助将不胜感激!如果需要任何进一步的信息,请告诉我。
问题在这里:
MEDIA_ROOT = '/static/media/'
MEDIA_ROOT 应该是绝对路径(的确如此,但它没有指向正确的目录)。它应该是这样的:
MEDIA_ROOT = '/var/www/example.com/mysite/static/media'