Top level home page routing for CBV-based website - - how to configure the urls.py properly?

Greetings Pythonistas!

I’m writing a Django CMS for a low traffic philosophy society. It’s like a blog.

I’m building the navbar and url navigation. I’m using a DetailView CBV and a single template to handle these four basic pages:

  • Home
  • About
  • Podcasts
  • Contact

Pretty standard website layout / usecase. When a web visitor clicks on one of those list items from the navigation menu, the urls.py successfully routes the visitor to the right corresponding addresses such as:

  • http://localhost:8000/home
  • http://localhost:8000/about
  • http://localhost:8000/podcasts
  • http://localhost:8000/contact

So far so good.

My goal is to have Django serve the home page at the top level parent address http://localhost:8000/ without the “home” slug at the end (suffix). But right now, when I navigate to http://localhost:8000/, Django serves a 404 and I can’t wrap my head around how to reconfigure my two urls.py to accomplish this desired outcome.

Here is my web app’s urls.py:

from django.contrib import admin
from django.urls import path, include
from .views import PageView

app_name= 'landings'

urlpatterns = [
   path('<str:slug>/', PageView.as_view(),name='home'),
]

In the past, what I normally would do, for the first path() argument, I’d substitute an empty string like it appears here: path('', views.home, name='home').Notice the empty string as fthe first paramer. So I tried placing this line - - path('', PageView.as_view(),name='home') - - above the path() in the code snippet above but then Django throws an “AttributeError at / Generic detail view PageView must be called with either an object pk or a slug in the URLconf.” So that isn’t working in this case since I am exploring this new CBV approach to generate pages.

What do I need to change in my urls.py above (or any of my other project files below) to get Django to serve the home page at the top level address without a “/home” suffix appended to the end of the domain name?

Here is my project urls.py:

from django.contrib import admin
from django.urls import path, include


urlpatterns = [
   path('admin/', admin.site.urls),
   path('', include('landings.urls')),
   path('articles/', include('articles.urls')),
   path('contributors/', include('contributors.urls')),
]

_navbar.html:

{% load static %}


<!-- Header Section -->
<header class="header">
   <div class="container container--narrow">
       <a href="{% url 'landings:home' 'home' %}" class="header__logo">
           <img src="Thelema_static_image_needed_here" alt="DevSearch Logo" />
       </a>


       <nav class="header__nav">
           <input type="checkbox" id="responsive-menu" />
           <label for="responsive-menu" class="toggle-menu">
               <span>Menu</span>
               <div class="toggle-menu__lines"></div>
           </label>
           <ul class="header__menu"> 
               <li class="header__menuItem"><a href="/">Home</a></li>
               <li class="header__menuItem"><a href="{% url 'landings:home' 'about' %}">About</a></li> 
               <li class="header__menuItem"><a href="{% url 'landings:home' 'podcasts' %}">Podcasts</a></li>      
               <li class="header__menuItem"><a href="{% url 'landings:home' 'contact' %}">Contact</a></li>    
           </ul>
       </nav>
   </div>
</header>

When clicking the first unordered list menu item hyperlink Home, the traceback in my Django terminal is simply:

Not Found: /
[05/Mar/2023 10:01:58] "GET / HTTP/1.1" 404 2467

The 404 showing in my browser, Django appears to be looking for the page but can’t find it and chokes at this line in my url routing: <str:slug>/ [name='home']

template:

{% extends 'base.html' %}

{% block content %}

   {% if contents %}

      {{ contents.body|safe }}

   {% endif %}

{% endblock %}

Here is my concise CBV:

from django.views.generic import DetailView
from .models import PageContent


class PageView(DetailView):
   model = PageContent
   template_name = "landings/page_detail.html"
   context_object_name = 'contents' 

My web app models.py:

from django.db import models
from ckeditor.fields import RichTextField
# from django.template.defaultfilters import slugify

class PageContent(models.Model):
   # title = models.CharField(max_length=200)
   slug = models.SlugField(null=False, unique=True, blank=True)
   page_type = models.CharField(max_length=20)
   body = RichTextField(config_name='default',max_length=300000,blank=True, null=True)

   def __str__(self):
       return f'{self.page_type}'

You can pass arguments to your view function in the url definition. See URL dispatcher | Django documentation | Django