从Heroku运行collectstatic运行成功,但是无法将文件推送到AWS,在本地运行成功

时间:2019-11-15 22:00:09

标签: django heroku amazon-s3

我正在尝试使用S3在Heroku上运行基本的Django应用,以同时提供静态文件和媒体文件。

当我使用python3 manage.py collectstatic在本地运行服务器时,静态文件将被收集并放置到S3存储桶中新创建的/ static /文件夹中。

运行heroku run python3 manage.py collectstatic时,我被告知静态文件已被收集并复制到/ app / staticfiles(在未禁用collectstatic的构建中,它已被收集并复制到/ tmp / build_ [id] / staticfiles) 。什么都没有添加到我的S3存储桶中;查看Heroku上的应用程序文件结构,没有文件夹/ app / staticfiles;该应用程序没有名为/ staticfiles的文件夹;而且我只有一个S3存储桶,所以我不会无意间推错了存储桶。最后,我已经四倍检查了开发环境和生产环境的设置是否匹配(在适当的地方)。

我的直觉是django.contrib.staticfiles对于静态文件应该在哪里结束有很强的见解,并且在生产后就覆盖了我对AWS(aws_settings.py)的设置。任何有关如何解决此问题的指示,深表感谢!

settings.py

import os
import dj_database_url
import dotenv
import django_heroku


BASE_DIR = os.path.dirname(
                os.path.dirname(
                    os.path.abspath(__file__)))
dotenv_file = os.path.join(BASE_DIR, ".env")

if os.path.isfile(dotenv_file):
    #DEV_ENV
    dotenv.load_dotenv(dotenv_file)
    os.environ['ENVIRONMENT']='DEV'
    from .envsettings.dev_settings import *

elif os.getenv('TEST_ENV', None):
    #TEST_ENV
    os.environ['ENVIRONMENT']='TEST'
    from .envsettings.test_settings import *

else:
    os.environ['ENVIRONMENT']='PROD'
    from .envsettings.prod_settings import *

# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp.apps.MyAppConfig',
    'accounts.apps.AccountsConfig',
    'storages',
    'django_clamd',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'myapp.urls'

TEMPLATES = [

    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'templates'),
        ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'myapp.wsgi.application'

#ugly hack, probably a better way
if os.environ['ENVIRONMENT']=='PROD':
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
            }
        }
    DATABASES['default'].update(dj_database_url.config(conn_max_age=500))
    django_heroku.settings(locals())

dev_settings.py

import os
import dotenv
SECRET_KEY='shhhh'
DEBUG = True

ALLOWED_HOSTS = ['*',]

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'myapp',
        'USER': 'user',
        'PASSWORD': 'admin',
        'HOST': 'localhost',
        'PORT':'',

    }
}

from .aws_settings import *

prod_settings.py

import os
from .aws_settings import *

SECRET_KEY = os.environ.get('SECRET', '')
DEBUG = False
ALLOWED_HOSTS = ['myapp.herokuapp.com',]

aws_settings.py

import os
BASE_DIR = os.path.dirname(
            os.path.dirname(
                os.path.dirname(
                    os.path.abspath(__file__))))

#S3 settings
DEFAULT_FILE_STORAGE = 'custom_storages.MediaStorage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID', '')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY', '')
AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME', '')
AWS_QUERYSTRING_AUTH = False
AWS_S3_CUSTOM_DOMAIN = AWS_STORAGE_BUCKET_NAME + '.s3.amazonaws.com'
AWS_LOCATION = 'static'

#static media settings
STATIC_URL = 'https://' + AWS_STORAGE_BUCKET_NAME + '.s3.amazonaws.com/static/'
MEDIA_URL = 'https://' + AWS_STORAGE_BUCKET_NAME + '.s3.amazonaws.com/media/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
STATIC_ROOT = 'static'
MEDIA_ROOT = 'media'
ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/'

STATICFILES_FINDERS = ('django.contrib.staticfiles.finders.FileSystemFinder',
                       'django.contrib.staticfiles.finders.AppDirectoriesFinder',)

customstorages.py

from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage

class MediaStorage(S3Boto3Storage):
    location = settings.MEDIA_ROOT

1 个答案:

答案 0 :(得分:0)

This is the resolution

django_heroku.settings(locals())覆盖了我的STATIC_URL。主要解决办法是用django_heroku.settings(locals(), staticfiles=False)替换它。

还有一个问题,我的STATICFILES_DIRS包含我的STATIC_ROOT(在运行python3 manage.py runserver --insecure时未被发现)。