So I've created several apps in my Django project and I have one main app called main_app.
The other apps are called profile_app, settings_app, messages_app.
The issue:
The issues that I have is that whenever I try to run a certain view function from e.g profile_app in main_app using the app namespace and URL name (e.g profilepage_app:"profile-redirect"), I receive a 404 error stating "Page not found".
I have done the following:
So the problem is that whatever link from all apps (except main_app) that I try to display in the browser generats the "Page not found"-error.
My questions:
The error:
My view:
from django.conf import settings
from django.shortcuts import render, redirect
from django.views.generic import View
from profile_app.forms import *
from profile_app.models import *
from messages_app.models import Message
user = settings.AUTH_USER_MODEL
# Create your views here.
## Redirect to user profile from the navbar
class ProfilePageView(View):
model = ProfilepageMember
template_name = "profile_app/profilepage.html"
def get(self, request, user_name):
user_related_data = ProfilepageMember.objects.filter(member__username = user_name)
context = {"user_related_data": user_related_data}
return render(request, self.template_name, context)
My URLS:
"""
URL configuration for bodyswap_project project.
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.2/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("", include("auth_app.urls")),
path("", include("main_app.urls")),
path("", include("profile_app.urls")),
path("", include("messages_app.urls")),
path("", include("settings_app.urls")),
]
Settings:
"""
"""
Django settings for body project.
Generated by 'django-admin startproject' using Django 4.2.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""
from pathlib import Path
import os
from dotenv import load_dotenv
load_dotenv()
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.getenv("SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.getenv("DEBUG")
ALLOWED_HOSTS = []
# HTTPS settings
# Set this to True in production to avoid transmitting the CSRF cookie over HTTP accidentally.
CSRF_COOKIE_SECURE = False
# Set this to True in production to avoid transmitting the CSRF cookie over HTTP accidentally.
SESSION_COOKIE_SECURE = False
# Change to True in production
SECURE_SSL_REDIRECT = False
# HSTS settings
# SECURE_HSTS_SECONDS = 31536000 # 1 year
# SECURE_HSTS_PRELOAD = True
SECURE_HSTS_INCLUDE_SUBDOMAINS = False
# Email settings for the contact form
# Used only during development
EMAIL_HOST = os.getenv("EMAIL_HOST")
EMAIL_HOST_USER = os.getenv("EMAIL_HOST_USER")
EMAIL_HOST_PASSWORD = os.getenv("EMAIL_HOST_PASSWORD")
EMAIL_PORT = os.getenv("EMAIL_PORT")
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Installed apps
'main_app.apps.MainAppConfig',
'auth_app.apps.AuthAppConfig',
'profile_app.apps.ProfileAppConfig',
'settings_app.apps.SettingsAppConfig',
'messages_app.apps.MessagesAppConfig',
]
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 = 'body.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 = 'body.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/4.2/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.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/
STATIC_URL = 'static/'
STATICFILES_DIRS = [
BASE_DIR / "static"
]
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# This is set when creating a custom user model.
AUTH_USER_MODEL = 'main_app.Member'
I appreciate all help.
Why does this happen?
You included the profilepage/urls.py
module in the URLs, but likely after you included the static
paths somewhere.
How can I resolve this issue?
You normally define the static and media paths at the root urls.py
after all other paths, such that it is only used if the matches of all other paths fail, so:
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import include, path
urlpatterns = (
[
path('admin/', admin.site.urls),
path('', include('auth_app.urls')), # 🖘 no static/media urls
path('', include('main_app.urls')), # 🖘 no static/media urls
path('', include('profile_app.urls')), # 🖘 no static/media urls
path('', include('messages_app.urls')), # 🖘 no static/media urls
path('', include('settings_app.urls')), # 🖘 no static/media URLs
]
+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
+ static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
)
It is thus important that the auth_app.urls
, main_app.urls
, profile_app.urls
, messages_app.urls
and settings_app.urls
do not contains the static/media paths. Strictly speaking that is not a problem either, as long as these are not "wildcards" that will match any path, but as you found out, that is easily the case.
Has this something to do with my settings file?
No: The order of the URLs is important: Django will match these top to bottom, and the first pattern that matches will "fire". If you thus have a path pattern that matches any path, it will always fire, and Django will thus never look to any paths further in the chain.
Subclassing the View
class directly is often not necessary. In this case your view looks like a DetailView
[Django-doc]. By using a DetailView
instead of a simple View
, you often do not have to implement a lot of boilerplate code.
from django.shortcuts import get_object_or_404
from django.views.generic import DetailView
class ProfilePageView(DetailView):
model = ProfilepageMember
template_name = 'profile_app/profilepage.html'
context_object_name = 'user_related_data'
def get_object(self, *args, **kwargs):
return get_object_or_404(ProfilepageMember, member__username=user_name)