Error 500 on certain pages

Hello!

I have deployed my project on Heroku and at first everything worked fine. The site was live.

But for some reason (I don’t remember what I did) I started to get error 500 on almost all URLs. I’ve created custom error pages to display.

Neither the Heroku logs or Django throws any form of errors. The only thing I see on when I run this command:

heroku logs

is:

2024-11-23T23:31:34.129978+00:00 heroku[router]: at=info method=GET path="/" host=www.exampel.se request_id=4557ecdc-110e-4932-b353-f9019f2804d9 fwd="213.204.198.19" dyno=web.1 connect=2ms service=235ms status=500 bytes=7986 protocol=https

I will share my settings file here if someone could please take a look and hopefully have a sharper eye than I do. Also, please feel free to share some feedback on my settings:

General settings:

import os
from pathlib import Path

from django.urls import reverse_lazy
from dotenv import load_dotenv

BASE_DIR = Path(__file__).resolve().parent.parent

load_dotenv()


INSTALLED_APPS = [
    'whitenoise.runserver_nostatic', # Must be at the top
    'anymail',
    'daphne',
    'channels',
    'main_app',
    'auth_app',
    'profile_app',
    'settings_app',
    'messages_app',
    'media_app',
    'diary_app',
    'hitcount',
    'debug_toolbar',
    'django.contrib.admindocs',
    'django_filters',
    'crispy_forms',
    'constrainedfilefield',
    'schema_graph',
    # 'silk',

    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    # The debug middleware must be placed first
    "debug_toolbar.middleware.DebugToolbarMiddleware",
    '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',
    'django.contrib.admindocs.middleware.XViewMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    # 'silk.middleware.SilkyMiddleware',
]

AUTHENTICATION_BACKENDS = ["django.contrib.auth.backends.AllowAllUsersModelBackend"]

ROOT_URLCONF = 'my_project.urls'

STORAGES = {
    "default": {
        "BACKEND": "django.core.files.storage.FileSystemStorage",
    },
    "staticfiles": {
        "BACKEND": "whitenoise.storage.CompressedManifestStaticFilesStorage",
    },
}
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'


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',
                'my_project.context_processors.django_env.django_env',
            ],
        },
    },
]


WSGI_APPLICATION = 'my_project.wsgi.application'
ASGI_APPLICATION = "my_project.asgi.application"


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

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

AUTH_USER_MODEL = 'main_app.Member'


HITCOUNT_KEEP_HIT_ACTIVE = {'days': 365} # Repeated hits on the same object are not counted for a year. 
HITCOUNT_HITS_PER_IP_LIMIT = 0 # Unlimited numner of hits from a certain IP-address
HITCOUNT_KEEP_HIT_IN_DATABASE = {'days': 365} # The samme time limit as each post exist

LANGUAGE_CODE = 'sv-se'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_TZ = True




STATIC_URL = '/static/'
MEDIA_URL = "/user_uploads/"

STATIC_ROOT = os.path.join(BASE_DIR.parent, "staticfiles/") # Path must be absolute
MEDIA_ROOT = os.path.join(BASE_DIR.parent, 'user_uploads/') # Path must be absolute

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

SESSION_EXPIRE_AT_BROWSER_CLOSE = True

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

DEFAULT_FROM_EMAIL = os.environ.get("DEFAULT_FROM_EMAIL")
SERVER_EMAIL = os.environ.get("SERVER_EMAIL")

LOGIN_REDIRECT_URL = reverse_lazy("main_app:roomsPage")
LOGIN_URL = reverse_lazy("auth_app:signin")
LOGOUT_URL = reverse_lazy("auth_app:signin")

LOGOUT_REDIRECT_URL = reverse_lazy("auth_app:signin")

ALLOWED_IMAGE_EXTENSIONS = ["JPEG", "JPG", "PNG"]
ALLOWED_VIDEO_EXTENSIONS = []

ALLOWED_NUMBERS_OF_IMAGES = 10
ALLOWED_NUMBER_OF_VIDEOS = 10
DATA_UPLOAD_MAX_NUMBER_FILES = 10

MAX_UPLOAD_VIDEO_SIZE = 104_857_600  # 100 MB
MAX_UPLOAD_PHOTO_SIZE = 104_857_6  # 1 MB

MAX_IMAGE_HEIGHT = 2000  # 2000 pixels
MAX_IMAGE_WIDTH = 2000  # 2000 pixels
ALLOWED_IMAGE_TYPES = ['image/jpeg', 'image/png', 'image/jpg']
ALLOWED_VIDEO_TYPES = ['video/mp4', 'video/quicktime', 'video/x-msvideo', 'video/x-matroska']


MAX_PROFILE_VISITORS = 30

MAX_ROOM_PER_USER = 10 # Max number of rooms per user instance

MAX_CHATMESSAGE_LENGTH = 250
MAX_TEXTFIELD_LENGTH = 500
URL_EXTENSION_LENGTH = 10
MAX_NUMBER_OF_ONLINE_MEMBERS_TO_DISPLAY = 150

PROFILE_DESCRIPTION_LENGTH = 2000
GROUP_PROFILE_INTRODUCTION_LENGTH = 3000
GROUP_PROFILE_RULES_LENGTH = 3000
GROUP_PROFILE_WISHES_LENGTH = 3000

DATA_RETENTION_PERIOD = 90 # days
DELETE_SIGNIN_HISTORY_AFTER = 7
DELETE_ACCOUNT_OLDER_THAN = 730 # 2 years
DELETE_ROOMS_OLDER_THAN = 365 # 1 year
DELETE_CHATROOMS_OLDER_THAN = 365 # 1 year

MAX_DIARY_LENGTH = 3000

DATE_INPUT_FORMATS = ["%Y-%m-%d"]
DATETIME_INPUT_FORMATS = ["%Y-%m-%d %H:%M"]

MAGIC_FILE_PATH = r"C:\Windows\System32\magic.mgc"
```

```

Production settings:

```
import dj_database_url

from .settings import *

DEBUG = False

ALLOWED_HOSTS = [".exampel.com", ".my-project-f330a5d3af70.herokuapp.com"]
    
ADMINS = [("admin", os.environ.get("ADMIN_EMAIL_ADDRESS"))]


SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_SECONDS = 31536000  # 1 year
SECURE_HSTS_PRELOAD = True
SECURE_HSTS_INCLUDE_SUBDOMAINS = True

GEOIP_PATH = os.path.join(BASE_DIR.parent, 'geoip/')

SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

EMAIL_BACKEND = 'anymail.backends.mailgun.EmailBackend'

ANYMAIL = {
    'MAILGUN_API_KEY': os.environ.get("MAILGUN_API_KEY"),
    'MAILGUN_SENDER_DOMAIN': os.environ.get("MAILGUN_SENDER_DOMAIN"),
    'MAILGUN_API_URL': os.environ.get("MAILGUN_API_URL"),
}


EMAIL_USE_TLS = True
DEFAULT_FROM_EMAIL = os.environ.get("DEFAULT_FROM_EMAIL")
SERVER_EMAIL = os.environ.get("SERVER_EMAIL")

SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default'
SESSION_COOKIE_AGE = 7200 # 2 h
SESSION_COOKIE_SECURE = True

CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
        "LOCATION": os.environ.get("MEMCACHEDCLOUD_SERVERS"),
    }
}

DATABASES = {
        "default": dj_database_url.config(
            conn_max_age=600,
            conn_health_checks=True,
            ssl_require=True,
        ),
    }


CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": [{"address": os.environ.get("REDIS_CLOUD_URL")}],
        },
    },
}

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': '[%(asctime)s] %(levelname)s %(name)s: %(message)s'
        },
        'verbose': {
            'format': '[%(asctime)s] - %(levelname)s - %(name)s - %(module)s - %(process)d %(thread)d: %(message)s'
        },
    },
    
    'handlers': {
        'file': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(BASE_DIR, "logg-files", "production", "prod-log-file"),
            'maxBytes': 1024*1024*5,  # 5MB
            'backupCount': 5,
            'formatter': 'verbose',
        },
        'user_signin_history': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(BASE_DIR, "logg-files", "production", "signInHistory"),
            'maxBytes': 1024*1024*5,  # 5MB
            'backupCount': 5,
            'formatter': 'verbose',
        },
        'deletion_failed_handler': {
            'level': 'ERROR',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(BASE_DIR, "logg-files", "production", "account_deletion_failed_loggs"),
            'maxBytes': 1024*1024*5,  # 5MB
            'backupCount': 5,
            'formatter': 'verbose',
        },
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
            'formatter': 'verbose',
            'include_html': True,
        },
        'password_reset': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(BASE_DIR, "logg-files", "production", "password_reset_request"),
            'maxBytes': 1024*1024*5,  # 5MB
            'backupCount': 5,
            'formatter': 'verbose',
        },
        'successful_sigins': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(BASE_DIR, "logg-files", "production", "successful_signins"),
            'maxBytes': 1024*1024*5,  # 5MB
            'backupCount': 5,
            'formatter': 'verbose',
        },
        'failed_signins': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(BASE_DIR, "logg-files", "production", "failed_signins"),
            'maxBytes': 1024*1024*5,  # 5MB
            'backupCount': 5,
            'formatter': 'verbose',
        },
        'email_confirmation_error': {
            'level': 'ERROR',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(BASE_DIR, "logg-files", "production", "email_account_registered_confi_error"),
            'maxBytes': 1024*1024*5,  # 5MB
            'backupCount': 5,
            'formatter': 'verbose',
        },
    },
    
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'INFO',
            'propagate': True,
        },
        'django.request': {
            'handlers': ['file', 'mail_admins'],
            'level': 'ERROR',
            'propagate': False,
        },
        'django.security': {
            'handlers': ['file', 'mail_admins'],
            'level': 'ERROR',
            'propagate': False,
        },
        'successful_signins': {
            'handlers': ['successful_sigins'],
            'level': 'INFO',
            'propagate': False,
        },
        'failed_signins': {
            'handlers': ['failed_signins'],
            'level': 'INFO',
            'propagate': False,
        },
        'password_reset_request': {
            'handlers': ['password_reset'],
            'level': 'INFO',
            'propagate': False,
        },
        'deletion_logger': {
            'handler': ['deletion_failed_handler'],
            'level': 'ERROR',
            'propagate': False,
        },
        'email_confirmation_error': {
            'handler': ['email_confirmation_error'],
            'level': 'ERROR',
            'propagate': False,
        },
    },
}

```

Try installing the Sentry add-on, which will enable you to see detailed reports of 500 errors, including the traceback.

Thank you!

I added Sentry to my project and can now see the full error traces.

The error that I see is:

django.db.utils.ProgrammingError: relation "main_app_member" does not exist
LINE 1: ...gin_from_city", "main_app_member"."is_staff" FROM "main_app_...

I have created the migration files and migrated, both in sqlite dev database and PostgresSQL.

When I run the command heroku run python manage.py showmigrations, I see that all the migration files has been created.

But for some reason, I see the error I shared above.

Without seeing any code it’s hard to know what the issue is. Rough things I’d look at:

  • You have a Member model in your main_app app?
  • I’d look through the migration files to check there’s one that creates it in the database.
  • I’d do showmigrations again and check that there’s an [X] next to each one indicating it’s been applied.
  • I’d check it has been created in the database.