Why can't I add static files in my django proj

2019-07-16 09:45发布

问题:

I'm trying to build a Django app for Heroku and have gone through the Polls tutorial and Heroku documentation

When serving the basic Django-heroku app with heroku local or python3 manage.py runserver I can see that some static files are loaded just fine (/static/lang-logo.png specifically). But when I add my main.css and run python3 manage.py collectstatic the css file never shows up and the import in my index.html never loads.

I've ready that whitenoise is best for serving static files in a django app so I'm using that and have set my settings.py based on many of the responses to similar questions here.

Collectstatic appears to be working (see below). I've been banging my head against this for literally days and have gone through dozens of related questions here and nothing seems to cut it. I have reached the end of the internet and now you are my only hope. My code is below and I'll update the question if I realize I've missed something relevant.

Settings.py

"""
Django settings for gettingstarted project.

Generated by 'django-admin startproject' using Django 2.0.

For more information on this file, see
https://docs.djangoproject.com/en/2.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
"""

import os
import django_heroku
import fred

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'CHANGE_ME!!!! (P.S. the SECRET_KEY environment variable will be used, if set, instead).'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'hello'
]

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',
    'whitenoise.middleware.WhiteNoiseMiddleware',
]

ROOT_URLCONF = 'gettingstarted.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        '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 = 'gettingstarted.wsgi.application'


# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = 'hello/static/hello'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'hello/static/hello'),
)

django_heroku.settings(locals())

index.html

{% load staticfiles %}
{% load static %}

<link rel="stylesheet" type="text/css" href="{% static 'hello/screener.css' %}" />

Directory structure

/hello/static/hello/index.css

collectstatic output

Post-processed 'hello/screener.css' as 'hello/screener.4d9ca1ef5004.css'
Post-processed 'screener.css' as 'screener.4d9ca1ef5004.css'

121 static files copied to '/Users/user/Desktop/heroku-bayesian/python-getting-started/staticfiles', 151 post-processed.

回答1:

Change your STATIC_URL to /static/ and for testing purposes, just set your STATICFILES_DIR = ['hello/static/hello']. Whitenoise does not necessarily need to be 2nd. I run mine on the bottom and it works fantastic with my Django multi-tenant app on Heroku. I believe when you push to Heroku now, you will probably have to do a collectstatic again. If it complains about your static files when building after the first time, just disable it like Heroku says here.

Edit: By the way SQLite is not supported by Heroku and you will need to migrate over to postgres. This is something I did and never looked back. All you have to do is change the database information and engine and you are good to go.