Dynamic data in templates
We have different pieces in place: the
Post
model is defined in
models.py
, we have
post_list
in
views.py
and the template added. But how will we actually make our posts appear
in our HTML template? Because that is what we want to do – take some
content (models saved in the database) and display it nicely in our
template, right?
This is exactly what
views
are supposed to do: connect models and templates. In our
post_list
view
we will need to take the models we want to display and pass them to
the template. In a
view
we decide what (model) will be displayed in a template.
OK, so how will we achieve this?
We need to open our
blog/views.py
in our code editor. So far
post_list
view
looks like this:
blog/views.py
from django.shortcuts import render
def post_list(request):
return render(request, 'blog/post_list.html', {})
Remember when we talked about including code written in different
files? Now is the moment when we have to include the model we have
written in
models.py
. We will add the line
from .models import Post
like this:
blog/views.py
from django.shortcuts import render
from .models import Post
The dot before
models
means
current directory
or
current application
. Both
views.py
and
models.py
are in the same directory. This means we can use
.
and the name of the file (without
.py
). Then we import the name of the model (
Post
).
But what's next? To take actual blog posts from the
Post
model we need something called
QuerySet
.
QuerySet
You should already be familiar with how QuerySets work. We talked about them in Django ORM (QuerySets) chapter .
So now we want published blog posts sorted by
published_date
, right? We already did that in QuerySets chapter!
blog/views.py
Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
So, let's open the
blog/views.py
file in the code editor, and add this piece of code to the function
def post_list(request)
-- but don't forget to first add
from django.utils import timezone
:
blog/views.py
from django.shortcuts import render
from django.utils import timezone
from .models import Post
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'blog/post_list.html', {})
To display our QuerySet on our blog's post list, we have two things left to do:
-
Pass the
postsQuerySet to the template context, by changing therenderfunction call. We'll do this now. -
Modify the template to display the
postsQuerySet. We'll cover this in a later chapter.
Please note that we create a
variable
for our QuerySet:
posts
. Treat this as the name of our QuerySet. From now on we can refer to
it by this name.
In the
render
function we have one parameter
request
(everything we receive from the user via the Internet) and another
giving the template file (
'blog/post_list.html'
). The last parameter,
{}
, is a place in which we can add some things for the template to use.
We need to give them names (we will stick to
'posts'
right now). :) It should look like this:
{'posts': posts}
. Please note that the part before
:
is a string; you need to wrap it with quotes:
''
.
So finally our
blog/views.py
file should look like this:
blog/views.py
from django.shortcuts import render
from django.utils import timezone
from .models import Post
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'blog/post_list.html', {'posts': posts})
That's it! Time to go back to our template and display this QuerySet!
Want to read a little bit more about QuerySets in Django? You should look here: https://docs.djangoproject.com/en/5.1/ref/models/querysets/
Coach quiz for this chapter
Loading chapter quiz...