Jebediah15
Jebediah15

Reputation: 794

Deployed django app to heroku missing CSS / static files

Preface this by saying I have now read multiple posts on this question (including here, here, and here). What I understand is that the static url in settings.py needs a modification for heroku to run these static files. What I need, explained like I am a child, is what tweak to make to these static url when the static directory is nested within the app -- as this was a best practice imparted in a recent tutorial (if this is not the ideal practice I would appreciate being corrected).

Question 1: Should the media files be kept in a directory within the app or at the project level?

Question 2: If the media files are kept within a directory inside the app, like my directory below, then how am I supposed to modify the url in settings.py to load the static files once pushed to heroku?

My project structure is the following:

gvlabs
    __init__.py
    __init__.pyc
    settings.py
    settings.pyc
    urls.py
    urls.pyc
    wsgi.py
    wsgi.pyc
manage.py
Procfile
requirements.txt
runtime.txt
welcome
    __init__.py
    __init__.pyc
    admin.py
    admin.pyc
    apps.py
    hello.py
    migrations
    models.py
    models.pyc
    static
        css
        fonts
        images
        js
    templates
        welcome
            base.html
            comingsoon.html
            contact_us.html
            index.html
            post_list.html
    tests.py
    urls.py
    urls.pyc
    views.py
    views.pyc

settings.py

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

PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
PROJECT_DIR = os.path.join(PROJECT_ROOT,'../welcome')

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.9/howto/static-files/
#STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATIC_ROOT= os.path.join(PROJECT_DIR,'static')

STATIC_URL = '/welcome/static/'

# Extra places for collectstatic to find static files.
STATICFILES_DIRS = ()

# Simplified static file serving.
# https://warehouse.python.org/project/whitenoise/

STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'

Upvotes: 1

Views: 2925

Answers (1)

D. Evans
D. Evans

Reputation: 3292

  1. The main problem with your configuration is the STATIC_ROOT setting. You should change this to something like os.path.join(BASE_DIR, 'static_root').

    STATIC_ROOT should point to an empty directory (it doesn't need to exist, Django will create it if necessary) where Django can collect your static files together and do any necessary processing on them before it serves them. It is not the directory where you store your static files.

  2. Regardless of where you put your static files, you shouldn't need to change the STATIC_URL setting. Just leave it as /static/. The main reason for needing to change this is when you're serving static files via a CDN, when it would be set to something like https://my-cdn.example.com/static/

  3. I would keep static files in a directory at the project level. Sometimes, when creating a reusable app it makes sense to bundle everything together by storing its static files in a directory within the app. But most projects I've worked on have kept the main set of static files at the project level.

  4. It doesn't really matter where you put your static files as long as you tell Django where to find them. You do this by adding the path to the directory to the STATICFILES_DIRS setting like so:

    STATICFILES_DIRS = [
        os.path.join(PROJECT_DIR, 'static'),
    ]
    

    (Technically, if your static files are in an app directory Django should be able to find them automatically, but let's keep things simple and explicit.)

  5. As a side note: be careful not to use the term "media" here as that has a specific meaning in Django terminology where it refers to user-uploaded files like profile images rather than files that belong with your codebase like CSS and JavaScript files.

Upvotes: 7

Related Questions