8. Output from models
A Django model instance can’t ‘generate a webpage’—there is no ‘make_html()’ function. The model, and it’s data, must to be pushed into a template. The template both lays out the HTML, and pulls appropriate data from the model (and maybe formats the data also). This is a super‐flexible system used by every web‐framework I can think of (off‐the‐cuff). On the other hand, it’s more work than a CMS.
The previous steps 6 Static Files, and 7 Base Template, gave us the resources needed to generate webpages throughout the new website. Let’s look again at the app built in Step 4 New Apps, and set it up to generate webpages.
Setup
Base template
As constructed in the last step, these examples use a base template. If you do not have a base template, delete the blocks, or modify to comments,
To,
Template folder
Navigate into the ‘reviews’ app (or whatever app you were building). Even if you generated the app using ‘startapp’, you will not have a template folder. This is because some apps do not use or need templates.
Run this. If the name of your app is different, use that. Yes, the command creates two directories, one called ‘templates’, and one inside named after the app. I will not explain much—the nested directories are for namespacing, and are standard Django configuration,
Webpages for details
View
Right, let’s make a view. Views wire Django model instances to URLs (and can also gather extra information, and break up a model). Django calls views and webpages that display data from a model instance a ‘Detail’.
We’ll start with one of Django’s convenience views. In reviews/views.py, like this,
Template
The view passes information to a template. For the view we have constructed, with a DetailView, Django will search for a template that is in a pre‐configured place, with a preconfigured name.
The instance of the model is passed wholesale, and the the template code can break it up. Create /reviews/templates/reviews/review_detail.html, and add,
Note: We use the ‘human_title’ method on the object which constructs a title from ‘make’ and ‘model’ fields. May often be a simple ‘title’ field.
URL
Now configure to call the view from URLs in siteName/urls.py. For slug indexing, like this,
Or, for id indexing, like this,
Note that the path element must be called ‘pk’ (‘primary key’). That’s because that name in the URL definition is given to the DetailView, which will then look for that information when it tries to find the requested review. The code in DetailView can search for keys with the name ‘slug’ or ‘pk’—any other name will not work.
Test
For slugs you will need to know the slug name of any existing review,
For id/pks, you can guess a number,
Refs
Django tutorial on generic classes, https://docs.djangoproject.com/en/3.2/topics/class-based-views/generic-display/
Webpages for lists
View
Right, let’s make a view and template to display a list of the available model instances.
Another lump of code convenience, with a more common name ‘ListView’. In /review/views.py, make like this,
Template
In /reviews/templates/reviews/review_list.html,
Probably the most important conceptual note is this—remember when we made the model, we provided a method ‘get_absolute_url’? This is a trick in Django—Django code goes and looks which URL is used to launch model instance pages—the ‘DetailView’s. The code can then write those URLs into the weblinks. It’s a concept‐bending idea but, right now, I’d not think about it and bash in the code (at some point you’ll realize what is happening). The important thing is, we are going to generate links that join to all the available model instance webpages.
Smaller notes: the code uses the method on the object which constructs a title from ‘make’ and ‘model’ fields. Could easily use a ‘title’ field. And also, I’m using the name ‘review_list’ to access the data, but the generic data name ‘object_list’ will work also.
URL
In siteName/urls.py, like this,
Test
If that worked, now you do not need guess what name or id your model instance pages use. You have a list of weblinks and can jump to them.
Refs
Django tutorial on generic classes, https://docs.djangoproject.com/en/3.2/topics/class-based-views/generic-display/