23

I have gone through every other answer and cannot seem to get anything to work for me. I am following a tutorial and trying to push my master branch to heroku and get the error You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path. I am using Django 2.0 and python 3.6.3. The full traceback:

remote: -----> $ python manage.py collectstatic --noinput
remote:        Traceback (most recent call last):
remote:          File "manage.py", line 15, in <module>
remote:            execute_from_command_line(sys.argv)
remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
remote:            utility.execute()
remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/__init__.py", line 365, in execute
remote:            self.fetch_command(subcommand).run_from_argv(self.argv)
remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/base.py", line 288, in run_from_argv
remote:            self.execute(*args, **cmd_options)
remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/core/management/base.py", line 335, in execute
remote:            output = self.handle(*args, **options)
remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 189, in handle
remote:            collected = self.collect()
remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 114, in collect
remote:            handler(path, prefixed_path, storage)
remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 344, in copy_file
remote:            if not self.delete_file(path, prefixed_path, source_storage):
remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/management/commands/collectstatic.py", line 250, in delete_file
remote:            if self.storage.exists(prefixed_path):
remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/core/files/storage.py", line 308, in exists
remote:            return os.path.exists(self.path(name))
remote:          File "/app/.heroku/python/lib/python3.6/site-packages/django/contrib/staticfiles/storage.py", line 43, in path
remote:            raise ImproperlyConfigured("You're using the staticfiles app "
remote:        django.core.exceptions.ImproperlyConfigured: You're using the staticfiles app without having set the STATIC_ROOT setting to a filesystem path.
remote: 
remote:  !     Error while running '$ python manage.py collectstatic --noinput'.
remote:        See traceback above for details.
remote: 
remote:        You may need to update application code to resolve this error.
remote:        Or, you can disable collectstatic for this application:
remote: 
remote:           $ heroku config:set DISABLE_COLLECTSTATIC=1
remote: 
remote:        https://devcenter.heroku.com/articles/django-assets
remote:  !     Push rejected, failed to compile Python app.
remote: 
remote:  !     Push failed
remote: Verifying deploy...
remote: 
remote: !   Push rejected to obscure-spire-97107.
remote: 
To https://git.heroku.com/obscure-spire-97107.git
 ! [remote rejected] master -> master (pre-receive hook declined)

My settings.py

import os

# 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 = '5af%uw_wn*o#v$gp!dj1yrxf0#z+4_+&4$3f^kjh*fc7+ec4*9'

# 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',

    #added apps for project, my_apps
    'blog',
    'users',

    #third party apps
    'bootstrap3',

]

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 = 'book_project.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 = 'book_project.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_URL = '/static/'

#My settings
LOGIN_URL = 'users/login/'

#settings bootstrap3
BOOTSTRAP3 = {
    'include_jquery':True,
}

#Heroku settings
# ROOT_PATH = os.path.dirname(__file__)
if os.getcwd() == '/app':
    import dj_database_url
    DATABASES = {
        'default': dj_database_url.config(default='postgres://localhost')
    }

    SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

    ALLOWED_HOSTS = ['*']

    BASE_DIR = os.path.dirname(os.path.abspath(__file__)),
    STATIC_ROOT = os.path.join(BASE_DIR, 'static')
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR, 'static'),
    )

I tried getting rid of the if statement to see if that was the problem but no luck. Looking for any advice.

ratrace123
  • 976
  • 4
  • 12
  • 24
  • 5
    This might be irrelevant at this point but you have shared a secret key, which is a bad practice. As an example to new SO users you could replace it with "*****"? – Anders_K Dec 07 '18 at 07:22

4 Answers4

25

Summarizing ratrace's answer, the main solution is to add

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

to settings.py. Where STATIC_ROOT is the destination to where static files are copied and from where they are served when deploying the Django app.

stefanbschneider
  • 5,460
  • 8
  • 50
  • 88
  • If you run "python manage.py collectstatic", a folder named 'staticfiles" will be created at the same place where manage.py is, if the folder does not exits. – Helmut Darmüntzel May 12 '23 at 09:01
17

I was able to make this work by getting rid of the if statement all together and just having the following in my settings.py.

import dj_database_url
DATABASES = {
    'default': dj_database_url.config(default='postgres://localhost')
}

SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')

ALLOWED_HOSTS = ['*']

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)
ratrace123
  • 976
  • 4
  • 12
  • 24
2

I solved this issue following these three steps:

  1. Import the os module in the settings.py: import os
  2. Set the STATIC_ROOT variable to "staticfiles" in the settings.py: STATIC_ROOT = os.path.join(BASE_DIR,'staticfiles')
  3. Execute the "collectstatic" command: python manage.py collectstatic
Dos
  • 2,250
  • 1
  • 29
  • 39
ahnaimi
  • 21
  • 3
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Dec 25 '22 at 16:32
0

On this website it says to add this url pattern to your project:

urlpatterns += patterns(”, (r’^static/(?P.*)$’, ‘django.views.static.serve’, {‘document_root’: settings.STATIC_ROOT}),)

I haven't used heroku before but IF I understand correctly, it needs a path to send all the collected static files to. Usually that's in the server's settings. But the website above mentions that heroku uses an app which doesn't support static files deployment, and that's why you need a url pattern to make it get the static files from their respective places.

Also, read the entire tutorial first. They might mention your problem somewhere near the end of the tutorial in like a Notes section. Read the comments also if they exist.

Eyad Arafat
  • 601
  • 8
  • 19
  • i tried adding that to my url patterns and it was very broken. I will try going through the tutorial – ratrace123 Jan 26 '18 at 04:12
  • what exactly was the error when you added that url pattern? – Eyad Arafat Jan 26 '18 at 04:17
  • the `patterns` and `settings.STATIC_ROOT` showed up as unresolved references. I don think my app is set up for that. I have looked at a lot of similar questions and it seems like i just need to somehow set the ROOT directory which I am clearly doing wrong... – ratrace123 Jan 26 '18 at 04:36
  • Just one last try. Add these to urls.py: `url(r’^static/(?P.*)$’, ‘django.views.static.serve’, {‘document_root’: settings.STATIC_ROOT})` and `from django.conf import settings`. – Eyad Arafat Jan 26 '18 at 04:58