Page not found (404) upon Heroku Deployment
I have been having difficulties getting to deploy my Heroku app with my Django and React app. The error is as follows:
Page not found (404)
Request Method: GET
Request URL: https://true-friends-404.herokuapp.com/login/
Using the URLconf defined in truefriends.urls, Django tried these URL patterns, in this order:
admin/
^authors/$ [name='authors-list']
^authors\.(?P<format>[a-z0-9]+)/?$ [name='authors-list']
^authors/(?P<pk>[^/.]+)/$ [name='authors-detail']
^authors/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='authors-detail']
^$ [name='api-root']
^\.(?P<format>[a-z0-9]+)/?$ [name='api-root']
^posts/$ [name='posts-list']
^posts\.(?P<format>[a-z0-9]+)/?$ [name='posts-list']
^posts/(?P<pk>[^/.]+)/$ [name='posts-detail']
^posts/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$ [name='posts-detail']
^$ [name='api-root']
^\.(?P<format>[a-z0-9]+)/?$ [name='api-root']
swagger/ [name='schema-swagger-ui']
api/
api/auth/
friendrequest/ [name='friend_request_list']
friendrequest/accept/<int:fr_id>/ [name='friend_request_accept']
friendrequest/reject/<int:fr_id>/ [name='friend_request_reject']
friendrequest/<int:author_id>/ [name='friend_request_to_user']
authors/<int:author_id>/
authors/<int:author_id>/
posts/<int:post_id>/
comments/<int:comment_id>/
authors/<int:author_id>/inbox/
followers/ [name='followers_list']
following/ [name='following_list']
unfollow/<int:user_id>/ [name='unfollow_by_user_id']
unfriend/<int:user_id>/ [name='unfriend_by_user_id']
withdraw/<int:user_id>/ [name='withdraw_by_user_id']
truefriends/ [name='true_friends_list']
posts/<int:post_id>/
authors/<int:author_id>/
currentauthor/
^media/(?P<path>.*)$
The current path, login/, didn’t match any of these.
You’re seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
Here is the urls.py file
# import ...
post_router = routers.DefaultRouter()
post_router.register(r'posts', PostView, 'posts')
logged_in_post_router = routers.DefaultRouter()
logged_in_post_router.register(r'posts', LoggedInPostView, 'my-posts')
author_router = routers.DefaultRouter()
author_router.register(r'authors', AuthorView, 'authors')
post_like_router = routers.DefaultRouter()
post_like_router.register(r'likes', PostLikeView, 'post-likes')
author_like_router = routers.DefaultRouter()
author_like_router.register(r'likes', AuthorLikeView, 'author-likes')
post_comment_router = routers.DefaultRouter()
post_comment_router.register(r'comments', PostCommentView, 'post-comments')
author_comment_router = routers.DefaultRouter()
author_comment_router.register(r'comments', AuthorCommentView, 'author-comments')
schema_view = get_schema_view(
openapi.Info(
# add your swagger doc title
title="TrueFriends API",
# version of the swagger doc
default_version='v1',
# first line that appears on the top of the doc
description="Methods for the TrueFriends Social Network",
),
public=True,
)
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(author_router.urls)), #authors-list, authors-details?
path('', include(post_router.urls)), # posts-list, posts-details?
#path('schema/', get_schema_view(title="TrueFriends API", permission_classes=(permissions.AllowAny,))),
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
path('api/', include('User.urls')),
path('api/auth/', include("User.urls")),
path('friendrequest/', FRListView.as_view(), name="friend_request_list"),
path('friendrequest/accept/<int:fr_id>/', FRAcceptView.as_view(), name="friend_request_accept"),
path('friendrequest/reject/<int:fr_id>/', FRRejectView.as_view(), name="friend_request_reject"),
path('friendrequest/<int:author_id>/', FRSendView.as_view(), name="friend_request_to_user"),
path('authors/<int:author_id>/', include(post_router.urls)), # authors-list, authors-detail?
path('authors/<int:author_id>/', include(author_like_router.urls)), # likes-list, likes-detail?
path('posts/<int:post_id>/', include(post_like_router.urls)), # post-likes-list, post-likes-detail?
path('comments/<int:comment_id>/', include(post_like_router.urls)), # comments-likes-list, comments-likes-detail?
path('authors/<int:author_id>/inbox/', include('Inbox.urls')), # inbox-list, inbox-detail?
path('followers/', FollowersListView.as_view(), name="followers_list"),
path('following/', FollowingListView.as_view(), name="following_list"),
path('unfollow/<int:user_id>/', UnfollowView.as_view(), name="unfollow_by_user_id"),
path('unfriend/<int:user_id>/', UnfriendView.as_view(), name="unfriend_by_user_id"),
path('withdraw/<int:user_id>/', WithdrawView.as_view(), name="withdraw_by_user_id"),
path('truefriends/', TrueFriendsListView.as_view(), name="true_friends_list"),
path('posts/<int:post_id>/', include(post_comment_router.urls)), # post-comments-list, post-comments-detail?
path('authors/<int:author_id>/', include(author_comment_router.urls)), # author-comments-list, author-comments-detail?
path('currentauthor/', include(logged_in_post_router.urls)), # my-posts-list, my-posts-detail?
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
The following is settings.py:
"""
Django settings for truefriends project.
Generated by 'django-admin startproject' using Django 4.1.2.
For more information on this file, see
https://docs.djangoproject.com/en/4.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.1/ref/settings/
"""
from pathlib import Path
import datetime
import os
import django_heroku
import dotenv
import dj_database_url
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
dotenv_file = os.path.join(BASE_DIR, ".env")
if os.path.isfile(dotenv_file):
dotenv.load_dotenv(dotenv_file)
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.1/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 = True
ALLOWED_HOSTS = ['true-friends-404.herokuapp.com', '127.0.0.1:8000', 'localhost']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Third-party applications
'rest_framework',
'corsheaders',
'drf_yasg',
# Local applications
'User',
'Post',
'Like',
'FriendRequest',
'Comment',
'Inbox',
'Follow',
]
AUTH_USER_MODEL = 'User.Author'
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',
'corsheaders.middleware.CorsMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
]
ROOT_URLCONF = 'truefriends.urls'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'build')],
'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 = 'truefriends.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": os.path.join(BASE_DIR, "db.sqlite3")
}
}
if "DATABASE_URL" in os.environ:
# Configure Django for DATABASE_URL environment variable.
DATABASES["default"] = dj_database_url.config(
conn_max_age=600, ssl_require=True)
DATABASES["default"]["ENGINE"] = "django.db.backends.sqlite3"
DATABASES["default"]["NAME"] = os.path.join(BASE_DIR, "db.sqlite3")
# Enable test database if found in CI environment.
if "CI" in os.environ:
DATABASES["default"]["TEST"] = DATABASES["default"]
# Password validation
# https://docs.djangoproject.com/en/4.1/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/4.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
'rest_framework.authentication.SessionAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': datetime.timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': datetime.timedelta(days=14),
'ROTATE_REFRESH_TOKENS': True,
'BLACKLIST_AFTER_ROTATION': False,
'ALGORITHM': 'HS256',
'SIGNING_KEY': SECRET_KEY,
'VERIFYING_KEY': None,
'AUTH_HEADER_TYPES': ('JWT', 'Bearer'),
'USER_ID_FIELD': 'email',
'USER_ID_CLAIM': 'user_email',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
}
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/
STATIC_URL = 'static/'
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'staticfiles/static/')
]
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
CORS_ORIGIN_WHITELIST = [
'http://localhost:3000'
]
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'backend/media')
MEDIA_URL = '/media/'
# Activate Django-Heroku
django_heroku.settings(locals())
options = DATABASES['default'].get('OPTIONS', {})
options.pop('sslmode', None)
Any valid route I take on the deployed app gives the 404 error. It seems like my static files are not reachable. How would I fix this?