Resolving `AttributeError` for home / landing page routing with CBVs

I’m trying to wire up a CBV with a Model and routing for a brand new site I am building.

When I try landing on the home page, Django is showing an “AttributeError” at /home: “type object ‘Home’ has no attribute ‘Home’”.

Here is my landings/views.py:

from django.shortcuts import render
from django.views.generic import DetailView
from .models import Home
 
class HomeDetailView(DetailView):
   models = Home
   queryset = Home.objects.order_by('title')
   context_object_name = "content"
  
   def get_slug_field(self):
       self.models.Home.title

I realize the problem is with the way I am calling the get_slug_field. I tried this instead:

def get_slug_field(self):
       self.Home.title

Then Django shows: AttributeError at /home: ‘HomeDetailView’ object has no attribute ‘Home’

I’ve identified that the above two lines are the problem. But I am just not sure of the right way to call the slug title attribute. Can anyone clarify how to properly call get_slug_field?

Here is my web app’s landings/urls.py:

from django.contrib import admin
from django.urls import path, include
from .views import HomeDetailView
 
urlpatterns = [
   path('<str:slug>', HomeDetailView.as_view(),name='home'),
]

landings/models.py:

from django.db import models
 
class Home(models.Model):
   title = models.CharField(max_length=200)
   body = models.TextField(null=True, blank=True)

And I’ve populated some placeholder data in the Admin Dashboard for this web app.

Prohect base urls.py:

from django.contrib import admin
from django.urls import path, include
 
urlpatterns = [
   path('admin/', admin.site.urls),
   path('', include('landings.urls')),

The CBV attribute object contains the reference to the object in the detail view. (It’s also referenced by the attribute defined by the context_object_name attribute.)

So in this specific case, since the view is for a Home object, self.object is the “current” Home, and so self.object.title is the title for that instance of Home.

(Side note: It seems odd to me that you’re creating a link on a page to itself.)

Hi Ken:

Thanks for your reply.

I seem to have misuderstood your recommendation to use: self.object.title. I tried:

def get_slug_field(self):
    self.object.title

Shows a 404 as if the slug doesn’t exist. When I go to populate some placeholder content for objects int he db, when I try accessing the Admin Dashboard, it shows this Attribute Error: 'HomeDetailView' object has no attribute 'object'.

You are right, it is odd. My original task was to have Django serve a landing page at the top level parent web address, (ex. at http://127.0.0.1:7000/).

Here is the project-level urls.py:

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

Here was my app-level urls.py:

urlpatterns = [
    path('', HomeDetailView.as_view(),name='home'),
]

Then Django throws this error:

AttributeError at /
Generic detail view HomeDetailView must be called with either an object pk or a slug in the URLconf.

That’s the original issue that got me started researching and looking into using a slug. But now that you mention it, since using a slug isn’t really required and is misplaced, how do I resolve this slug AttributeError so that Django serves the home landing page as intended? What other information could I provide to help troubleshoot further?

edit: sp

What is get_slug_field supposed to supply?

(Note, I frequently recommend people reference both the Classy Class-Based View site as well as the CBV diagrams page to get an understanding of how CBVs work. I find this “unified view” of the CBVs easier to understand than the “class-based” description provided in the docs.)

What are you intending?

As the error message you’re quoting states, a DetailView must provide either a pk or slug as a parameter, you have your choice of one or the other. Not providing a parameter is not an option.

Side note to the side note:

I’m not sure from the context here why I wrote that - was this a continuation / redirection from another thread? If we’re looking at this thread as a conversation in itself, this doesn’t make sense.

My original line of questioning that I asked in my first post in this thread was completely misguided.

I arrived at a resolution.

For a community organization’s website for example, in general, there should only really be 1 ‘home’ page, 1 ‘contact us’ page, and 1 ‘about’ page. So in that use case, TemplateView is the correct generic CBV. Whereas for an organization’s blog, the generic DetailViewTemplate CBV would be appropriate one to use for the organization’s employees to write posts and publish content. And then a generic ListViewTemplate CBV would be the right one to render a page containing a record or list or archive of individual DetailViewTemplate titles sorted by date. This is the new architecture I am using based on my improved nuanced understanding of Django to build my CMS going forward.

In my previous posts, I was using DetailViews for the home page and fiddling around with slugs which I see now is completely the wrong approach.

This was not a continuation of a different thread. I think my prior misunderstanding of when to properly use Template/Detail/List View CBVs is the source of all the chaos earlier. Using a slug for a home page is indeed quite odd and way off the mark.

Working on this project tonight, so far I have re-wired up my views, url routing, and models. Lots of changes. The original tracebacks are gone. Django is serving my homepage.

My new obstacle is that the variable attributes (basic title and body data points) are not parsing / showing when Django serves the template. Here is my new forum thread working on this new issue: