Eureka! Thank you for your patience and for taking the time to write such detailed feedback and guidance so far, Ken. I got it working! (Partially). Django is serving the template with content, but I am still not quite there yet. We are noless making progress.
Leveraging DetailView -- Classy CBV again, as well as based on your suggested PageContent objects dbase call, I commented out all the repetitive class declarations in models.py and in views.py. I scrapped all 4 templates and am just using 1 now. It’s essentially a whole new web app.
For my use case, so far we’ve discussed a ‘home’ page and ‘about’ page but originally I also planned a page for ‘contact’ and ‘podcasts’. Previously, I had 4 separate models and 4 separate DetailViews in total to account for these pages. I have since got rid of all of that and have a single class model and single CBV.
Even though it still doesn’t fully work as intended, I already can identify the problem. I’ve tried a few different possibilities by swapping different variables and parameters but I still can’t quite get it right. After I share my latest source code below, I will provide an analysis of the problem as I see it as well as the things I’ve tried, albeit unsuccessfully so far.
Here we go.
Here is my (new) single model declaration:
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}'
The main difference there is the page_type
attribute that Ken recommended as well as the fact that I have cut out all the other class models.
Here is my views.py:
from django.views.generic import DetailView # TemplateView
from .models import PageContent # Home, Podcast, About, Contact
class PageView(DetailView):
model = PageContent
template_name = "landings/page_detail.html"
context_object_name = 'contents'
def get_object(self): # queryset=None # page_type
obj = PageContent.objects.get(page_type='home')
return obj
In the PageView, I have this: PageContent.objects.get(page_type='home')
dbase call which is what Ken recommended I try as well. Now I figure that the page_type
parameter’s string assignment with ‘home’ was supposed to be merely a temporary stop gap or placeholder because there is going to be more than one page_types
. Ken also indicated I’ll need to check to make sure there are no duplicates. One way to understand this clearly is when I change ‘home’ to ‘about’ or to ‘contact’, Django begins serving that corresponding data that I have entered into the Admin Dashboard. So what I am trying to figure out next is how to make the page_type
call dynamic. One way I can think of, or at least if I was working with an id
, would be to pass in a pk
variable which would be an integer. But in my case, I am working with a slug
which is a string. To this end, I’ve tried to make my string parameter dynamic by adding pk
to the get_object
method call and then changing page_type='home'
to page_type=pk
. That didn’t work. Next I tried changing page_type='home'
by integrating an f-string like this: page_type=f’{page_type}’
. That didn’t work either. I tried many other alternatives without success.
So a little more guidance here on how to make this page_type
variable dynamic, I think I will have reached a full resolution and can mark this thread as solved.
For what it is worth, here is my single custom template:
{% extends 'base.html' %}
{% block content %}
{% if contents %}
{{ contents.body|safe }}
{% endif %}
{% endblock %}
That’s a big change because in the past I had 4 templates which were basically all the same. Now I just have this one. I am no longer repeating myself here.
Finally, here is my urls.py which is also imperfect:
from django.contrib import admin
from django.urls import path, include
from .views import PageView #HomeView, AboutView, PodcastView, ContactView
app_name= 'landings'
urlpatterns = [
path('<str:slug>/', PageView.as_view(),name='home'),
]
I noticed that when I change the name
path parameter to one string or another, Django still serves the template with the same data, whether the data be for the ‘contact’ or ‘about’. I tried to make this ‘name’ parameter dynamic by using an f-string. No dice.
The only way to get Django to serve different data is if I change the page_type
parameter in the get_object() DetailView class method so I believe that is my main knowledge gap as described earlier.
Thanks again @KenWhitesell for your help and patience.