0

My django app works properly (without any errors) when Debug = True in settings.py, but when I switch it to Debug = False I get Server Error (500).

Plus I get:

  • The character encoding of the HTML document was not declared. The document will render with garbled text in some browser configurations if the document contains characters from outside the US-ASCII range. The character encoding of the page must be declared in the document or in the transfer protocol.

  • http://127.0.0.1:8000/favicon.ico 404 Not Found

My settings.py file:

"""
Django settings for zeynab_web project.

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

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 dj_database_url
from decouple import config
import cloudinary_storage

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


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

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

import logging
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
            'datefmt' : "%d/%b/%Y %H:%M:%S"
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    },
    'handlers': {
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': 'mysite.log',
            'formatter': 'verbose'
        },
    },
    'loggers': {
        'django': {
            'handlers':['file'],
            'propagate': True,
            'level':'DEBUG',
        },
        'MYAPP': {
            'handlers': ['file'],
            'level': 'DEBUG',
        },
    }
}

ALLOWED_HOSTS = ['*']


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    #'whitenoise.runserver_nostatic',
    'django.contrib.staticfiles',
    'cloudinary_storage',
    'cloudinary',

    # own apps
    'pages',
    'products',
]

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 = 'zeynab_web.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 = 'zeynab_web.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/'
MEDIA_URL = '/media/'

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

DEFAULT_FILE_STORAGE = 'cloudinary_storage.storage.RawMediaCloudinaryStorage'

CLOUDINARY_STORAGE = {
    'CLOUD_NAME': '---',
    'API_KEY': '---',
    'API_SECRET': '---'
}

#STATICFILES_STORAGE = 'whitenoise.storageCompressedManifestStaticFilesStorage'

# Email settings
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = '---'
EMAIL_HOST_PASSWORD = '---'
EMAIL_USE_TLS = True

django_heroku.settings(locals())

#update comment

My wsgi.py file:

"""
WSGI config for zeynab_web project.

It exposes the WSGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/
"""

import os

from django.core.wsgi import get_wsgi_application
#from whitenoise.django import DjangoWhiteNoise

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "zeynab_web.settings")

application = get_wsgi_application()
#application = DjangoWhiteNoise(application)

After reading forms

I tried ALLOWED_HOSTS = ['*'], but nothing changed.

I tried inserting

import logging
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format' : "[%(asctime)s] %(levelname)s [%(name)s:%(lineno)s] %(message)s",
            'datefmt' : "%d/%b/%Y %H:%M:%S"
        },
        'simple': {
            'format': '%(levelname)s %(message)s'
        },
    },
    'handlers': {
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': 'mysite.log',
            'formatter': 'verbose'
        },
    },
    'loggers': {
        'django': {
            'handlers':['file'],
            'propagate': True,
            'level':'DEBUG',
        },
        'MYAPP': {
            'handlers': ['file'],
            'level': 'DEBUG',
        },
    }
}

to my settings.py file to see logs for solving error, but no logs appeared in my terminal.

Edit:

Implemented @Dos 's code and get same error.

Here is my new settings.py file

import os
import django_heroku
import dj_database_url
from decouple import config
import cloudinary_storage

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# and here the rest of your local settings

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '---'

WSGI_APPLICATION = 'zeynab_web.wsgi.application'

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

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'whitenoise.runserver_nostatic',
    'django.contrib.staticfiles',
    'cloudinary_storage',
    'cloudinary',

    # own apps
    'pages',
    'products',
]

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

# 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


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

# Static files configuration
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = os.path.join(BASE_DIR, 'static/')
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)
#STATICFILES_STORAGE = 'whitenoise.storageCompressedManifestStaticFilesStorage'

# Media configuration
MEDIA_ROOT = os.path.join(BASE_DIR,'media')
MEDIA_URL = '/media/'
DEFAULT_FILE_STORAGE = 'cloudinary_storage.storage.RawMediaCloudinaryStorage'
CLOUDINARY_STORAGE = {
    'CLOUD_NAME': '---',
    'API_KEY': '---',
    'API_SECRET': '---'
}

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

django_heroku.settings(locals())

# Loading test/prod settings based on ENV settings
ENV = os.environ.get('ENV')

if ENV == 'prod':
    try:
        from .production_settings import *
        MIDDLEWARE.append('whitenoise.middleware.WhiteNoiseMiddleware',)
    except ImportError:
        pass

And production_settings.py file

import os

DEBUG = False

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

#DATABASES = {
#    'default': {
#       'ENGINE': 'django.db.backends.postgresql',
#        'NAME': os.environ.get('DB_NAME'),
#        'USER': os.environ.get('DB_USER'),
#        'PASSWORD': os.environ.get('DB_PASSWORD'),
#        'HOST': os.environ.get('DB_HOST'),
#        'PORT': '5432',
#    }
#}

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

# Password validation (I removed them in the local settings)
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'},
]

ALLOWED_HOSTS = (
    'ophrys.herokuapp.com',
    'localhost',
)

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

SECURE_SSL_REDIRECT = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True
  • 2
    `favicon.ico` looks like you are trying to serve static files. Check this documentation [Deploying static files](https://docs.djangoproject.com/en/3.1/howto/static-files/deployment/). Django does not serve static files in production. – Abdul Aziz Barkat Jan 26 '21 at 09:34
  • @AbdulAzizBarkat as you said to serve my static files I enabled whitenoise (it was commented), but no changes and same errors. – Nadir Alishly Jan 26 '21 at 10:49
  • Does this help you? [Django Whitenoise 500 server error in non debug mode](https://stackoverflow.com/questions/53859972/django-whitenoise-500-server-error-in-non-debug-mode) – Abdul Aziz Barkat Jan 26 '21 at 11:02
  • I tried `STATICFILES_STORAGE = 'whitenoise.storage.CompressedStaticFilesStorage'` instead of `STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'` and it do not changed anithing. – Nadir Alishly Jan 26 '21 at 11:17

2 Answers2

1

When you set DEBUG=False Django doesn't handle your static files anymore. The idea behind is that you need to setup a proper production system. I think you are using Heroku, so I attached here a (tested) configuration for your production settings file (I suggest you to create a dedicated file for prod settings, like in the example below).

settings.py:

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# and here the rest of your local settings
# ...

WSGI_APPLICATION = 'your-app-name.wsgi.application'

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

# Password validation
AUTH_PASSWORD_VALIDATORS = []

# Static files configuration
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = os.path.join(BASE_DIR, 'static/')
STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

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

# ...

# Loading test/prod settings based on ENV settings
ENV = os.environ.get('ENV')

if ENV == 'prod':
    try:
        from .production_settings import *
        MIDDLEWARE.append('whitenoise.middleware.WhiteNoiseMiddleware',)
    except ImportError:
        pass

production_settings.py (for Heroku):

import os

DEBUG = False

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

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ.get('DB_NAME'),
        'USER': os.environ.get('DB_USER'),
        'PASSWORD': os.environ.get('DB_PASSWORD'),
        'HOST': os.environ.get('DB_HOST'),
        'PORT': '5432',
    }
}

# Password validation (I removed them in the local settings)
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'},
]

ALLOWED_HOSTS = (
    'your-app-name.herokuapp.com',
    'localhost',
)

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'

SECURE_SSL_REDIRECT = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_SECURE = True

Your wsgi.py file is already ok. Make sure you have the Procfile, the requirements.txt file and you set your env var under the "Config Vars" section on Heroku dashboar (dashboard.heroku.com/your-app-name/axdos/settings). Here you need to set SECRET_KEY, DB_NAME, DB_USER, DB_PASSWORD, DB_HOST and finally ENV (this env needs to be equal to prod). You can find the db credentials under the dashboard.heroku.com/your-app-name/axdos/resources.

Dos
  • 2,250
  • 1
  • 29
  • 39
  • I have whitenoise to serve my static files. I don't understand the point. What is wrong with my settings file. – Nadir Alishly Jan 28 '21 at 09:21
  • I implemented your solution and get No module named 'sass_processor' on terminal – Nadir Alishly Jan 28 '21 at 09:25
  • Then I commented `'sass_processor.finders.CssFinder',` and get same error.(can see my edited code below) – Nadir Alishly Jan 28 '21 at 09:40
  • Yes sorry, the 'sass_processor.finders.CssFinder' was a typo, it's fine to comment it. You cannot use your static files in local with DEBUG=False in your local env. To use the env in Heroku you have to setup the env vars for settings file in the Heroku interface. But let's go step by step, are you able to run your project locally with DEBUG=True? – Dos Jan 28 '21 at 14:20
  • It runs without errors when `Debug = True`. But when I setup model you proposed it crashes (same 500 error) with `Debug = True`. I think that production_settings file is not linked with setting file, maybe because env vars as you said. And I used default database instead of postgresql, is that ok? – Nadir Alishly Jan 29 '21 at 07:17
  • You have two configuration: `settings.py ` for local development, and `production_settings.py ` for Heroku (production environment). You cannot use DEBUG=False is a configuration for production env only, because it forces you to use a proper configuration for static assets (avoiding the default provided by Django itself for development. Said that, why are you trying to use DEBUG=False in local? – Dos Jan 29 '21 at 15:34
  • For testing. But actually when I deploy it to heroku I get same errors. But not tested your configuration on heroku yet. I will comment after testing it. – Nadir Alishly Jan 30 '21 at 06:52
  • I don't now how to setup env on heroku, so it gives same error on heroku for now. – Nadir Alishly Feb 01 '21 at 10:04
  • It is very easy! Just go to dashboard.heroku.com/your-app-name/axdos/settings and add your env var under the "Config Vars" section. You need to set SECRET_KEY, DB_NAME, DB_USER, DB_PASSWORD, DB_HOST and finally ENV (this needs to be equal to 'prod'). You can find the db credentials under the dashboard.heroku.com/your-app-name/axdos/resources – Dos Feb 01 '21 at 10:46
  • I set config var like this: key:prod, value:???. But what should be it's value? It's blank for now. – Nadir Alishly Feb 02 '21 at 09:07
  • key:ENV, value:prod - Please look at the code in the settings file: ENV = os.environ.get('ENV'); if ENV == 'prod': – Dos Feb 04 '21 at 21:09
  • Any update @NadirAlishly? Does the solution that I suggested work for you? – Dos Feb 23 '21 at 14:05
  • Can you be more specific? Did you set up the env vars in Heroku console? – Dos Feb 24 '21 at 13:51
1

after adding add WhiteNoise to the MIDDLEWARE

MIDDLEWARE = [
  # 'django.middleware.security.SecurityMiddleware',
  'whitenoise.middleware.WhiteNoiseMiddleware',
  # ...
]

execute this command

python manage.py collectstatic --noinput
Belhadjer Samir
  • 1,461
  • 7
  • 15