尝试将静态文件上传到 S3 时,Django 一直使用错误的存储后端
Django keeps using wrong storage backend when trying to upload static files to S3
更新:错误不是由 django-storages 引起的,而是由 django-heroku 引起的
django-heroku 似乎覆盖了一些导致此行为的变量。请参阅下面我的回答。
我一直在使用 S3 作为其他 Django 应用程序的存储服务,但是对于一个新项目,Django 拒绝选择正确的后端并一直将文件放在我的本地文件系统而不是上传。
确切地说,在我安装 boto3 并调整 settings.py
之后,然后 运行 python manage.py collectstatic
,该命令一直将静态文件移动到 <my_project_path>/staticfiles
而不是启动上传到S3。
这是python manage.py collectstatic
的输出:
You have requested to collect static files at the destination
location as specified in your settings:
<my_project_path>/staticfiles
This will overwrite existing files!
Are you sure you want to do this?
Type 'yes' to continue, or 'no' to cancel:
我的设置:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
# Vendor
'storages',
'allauth',
'allauth.account',
'allauth.socialaccount',
'sass_processor',
'crispy_forms',
[..]
]
# static & media files
USE_S3 = config('USE_S3', cast=bool, default=True)
AWS_ACCESS_KEY_ID = config('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = config('AWS_SECRET_ACCESS_KEY')
AWS_DEFAULT_ACL = None
AWS_STORAGE_BUCKET_NAME = config('AWS_STORAGE_BUCKET')
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
AWS_S3_OBJECT_PARAMETERS = {
'CacheControl': 'max-age=86400',
}
AWS_LOCATION = 'static'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
if USE_S3:
MEDIA_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, 'media')
DEFAULT_FILE_STORAGE = '<my_app>.storage_backends.MediaStorage'
STATIC_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
else:
MEDIA_URL = '/media/'
STATIC_URL = '/static/'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'sass_processor.finders.CssFinder',
]
我的requirements.txt:
...
boto3==1.11.12
botocore==1.14.15
django-storages==1.9.1
jmespath==0.9.4
s3transfer==0.3.3
...
我尝试从上传有效的其他项目复制设置,重新检查 django-storages
文档,甚至安装了 boto3 等的确切版本以排除由于更新版本而导致的错误,检查了我的settings.py
如果在某个地方我忘记了一个冲突的设置,但我就是想不通为什么 Django 甚至不尝试上传。
非常感谢任何指点!
经过更多的挖掘,我找到了罪魁祸首。结果是 django-heroku 包导致了不需要的行为。
程序包自动设置 STATIC_ROOT='/static/'
,覆盖 settings.py
中的 AWS 位置。
您可以在设置 django-heroku 时通过设置 staticfiles=False
来禁用此行为,如下所示:
import django_heroku
django_heroku.settings(locals(), staticfiles=False)
我也意识到在其他应用程序中我成功地安装了 S3 运行,我什至没有使用 django-heroku,这就是导致我困惑的原因,也是我在设置中遗漏的一个差异之前的检查。
更新:错误不是由 django-storages 引起的,而是由 django-heroku 引起的
django-heroku 似乎覆盖了一些导致此行为的变量。请参阅下面我的回答。
我一直在使用 S3 作为其他 Django 应用程序的存储服务,但是对于一个新项目,Django 拒绝选择正确的后端并一直将文件放在我的本地文件系统而不是上传。
确切地说,在我安装 boto3 并调整 settings.py
之后,然后 运行 python manage.py collectstatic
,该命令一直将静态文件移动到 <my_project_path>/staticfiles
而不是启动上传到S3。
这是python manage.py collectstatic
的输出:
You have requested to collect static files at the destination
location as specified in your settings:
<my_project_path>/staticfiles
This will overwrite existing files!
Are you sure you want to do this?
Type 'yes' to continue, or 'no' to cancel:
我的设置:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
# Vendor
'storages',
'allauth',
'allauth.account',
'allauth.socialaccount',
'sass_processor',
'crispy_forms',
[..]
]
# static & media files
USE_S3 = config('USE_S3', cast=bool, default=True)
AWS_ACCESS_KEY_ID = config('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = config('AWS_SECRET_ACCESS_KEY')
AWS_DEFAULT_ACL = None
AWS_STORAGE_BUCKET_NAME = config('AWS_STORAGE_BUCKET')
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
AWS_S3_OBJECT_PARAMETERS = {
'CacheControl': 'max-age=86400',
}
AWS_LOCATION = 'static'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
if USE_S3:
MEDIA_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, 'media')
DEFAULT_FILE_STORAGE = '<my_app>.storage_backends.MediaStorage'
STATIC_URL = 'https://%s/%s/' % (AWS_S3_CUSTOM_DOMAIN, AWS_LOCATION)
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
else:
MEDIA_URL = '/media/'
STATIC_URL = '/static/'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'sass_processor.finders.CssFinder',
]
我的requirements.txt:
...
boto3==1.11.12
botocore==1.14.15
django-storages==1.9.1
jmespath==0.9.4
s3transfer==0.3.3
...
我尝试从上传有效的其他项目复制设置,重新检查 django-storages
文档,甚至安装了 boto3 等的确切版本以排除由于更新版本而导致的错误,检查了我的settings.py
如果在某个地方我忘记了一个冲突的设置,但我就是想不通为什么 Django 甚至不尝试上传。
非常感谢任何指点!
经过更多的挖掘,我找到了罪魁祸首。结果是 django-heroku 包导致了不需要的行为。
程序包自动设置 STATIC_ROOT='/static/'
,覆盖 settings.py
中的 AWS 位置。
您可以在设置 django-heroku 时通过设置 staticfiles=False
来禁用此行为,如下所示:
import django_heroku
django_heroku.settings(locals(), staticfiles=False)
我也意识到在其他应用程序中我成功地安装了 S3 运行,我什至没有使用 django-heroku,这就是导致我困惑的原因,也是我在设置中遗漏的一个差异之前的检查。