Why is Heroku returning a 500 server error when Django DEBUG is set to False?

Working locally, I'm able to visit mysite.com. Hosted on Heroku, I'm only able to access mysite.com if I have DJANGO_DEBUG set to True in my config vars. The following is my settings.py file:

from pathlib import Path
import os
from dotenv import load_dotenv
import dj_database_url
import django_heroku

load_dotenv()
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


SECRET_KEY = os.environ.get('DJANGO_SECRET_KEY')


# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.environ.get('DJANGO_DEBUG', '') != 'False'


ALLOWED_HOSTS = ['myprojectwebsite.herokuapp.com', 'www.mysite.com', 'mysite.com', 'localhost', '127.0.0.1']


INSTALLED_APPS = [
    'myprojectwebsite',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django_google_fonts',
    'django.contrib.sitemaps',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    '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 = 'myproject.urls'

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'detailed': {
            'format': '{levelname} {asctime} {module} {message} {pathname}:{lineno}',
            'style': '{',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'detailed',
        },
    },
    'loggers': {
        'script_logger': {
            'handlers': ['console'],
            'level': 'DEBUG',
        },
    },
}

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],  # Global templates folder
        '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',
                'django.template.context_processors.media',
                'myprojectwebsite.context_processors.resorts_by_location',
            ],
        },
    },
]

WSGI_APPLICATION = 'myproject.wsgi.application'


if DEBUG:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': os.environ.get('DB_NAME', 'myprojectdb'),
            'USER': os.environ.get('DB_USER', 'user'),
            'PASSWORD': os.environ.get('DB_PASSWORD', 'pass'),
            'HOST': os.environ.get('DB_HOST', 'localhost'),
            'PORT': os.environ.get('DB_PORT', ''),
        }
    }
else:
    DATABASES = {
        'default': dj_database_url.config(default=os.environ.get('DATABASE_URL'))
    }


LOGIN_REDIRECT_URL = '/'

LOGOUT_REDIRECT_URL = '/'

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.mailgun.org'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = os.getenv('MAILGUN_DOMAIN')
EMAIL_HOST_PASSWORD = os.getenv('MAILGUN_API_KEY')


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',
    },
]


LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True


STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]
STATIC_URL = '/static/'
GOOGLE_FONTS = ["Roboto"]
# Media files
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

SECURE_HSTS_SECONDS = 31536000  # 1 year
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

django_heroku.settings(locals())

I can access the /admin areas of my site, so I'm assuming this is a template problem or a file location problem. My project's root directory has a subdirectory entitled 'myprojectwebsite' and then another subdirectory entitled 'templates' where my website's html templates are for the various pages. I'm able to access these pages and templates just fine locally, or with Debug turned on, but not in production. I only receive a 500 error when trying to access any of my templates. As an example, this is my faq.html template:

{% extends 'base.html' %}
{% block title %}FAQs{% endblock %}
{% block description %}Example.{% endblock %}
{% block content %}
<div class="container mt-4">
    <h1>Frequently Asked Questions</h1>

    {% for faq in faqs %}
    <div class="faq-item">
        <p><strong>{{ faq.question }}</strong></p>
        <p>{{ faq.answer|safe }}</p>
    </div>
    {% endfor %}
</div>
{% endblock %}

And in my views.py file, this is the view for faqs, truncated for example purposes:

def faq_view(request):
    faqs = [
        {"question": "Question", "answer": "Answer"},
    ]
    return render(request, 'faq.html', {'faqs': faqs})

And then in my urls.py file, here is the related path:

    path('frequently-asked-questions/', faq_view, name='faq'),

I'm not sure what else I'm doing wrong. Could someone point me in the right direction?

I tried changing the config vars in heroku, the settings.py file in many different ways, I ran collectstatic as well as the migrate function. It appears there are no database issues because admin is working properly.

Back to Top