Querying & Displaying Models
Now we have some blog posts in our database we can update our view and template to display them.
Open blog/views.py
and import our Post
model at the top of the file:
from .models import Post
To load our posts from the database we execute a query on the Post.objects
attribute. We want all
posts so we use Post.objects.all()
. We then want to pass the posts into our template so we update
the dictionary passed into the render
function:
def posts(request):
posts = Post.objects.all()
return render(request, "posts.html", {"name": "Alice", "posts": posts})
Inside blog/templates/posts.html
, we wish to loop over all our posts and display the title and the
body of the post. We can do this in a Django template using the {% for ... %}
template tag which
is terminated with {% endfor %}
:
<body>
<h1>Welcome to {{ name }}'s Blog!</h1>
{% for post in posts %}
<h2>{{ post.title }}</h2>
<p>{{ post.body }}</p>
{% endfor %}
</body>
For each post in our database, this for loop will generate a heading tag containing the post title
and a paragraph tag (<p>
) containing the body of the post. Save this and go back to
your homepage and you should see the posts that you entered in the admin
interface.
Challenges
-
We are currently showing all posts, including those where
public
is set to false in the database. We can get only posts wherepublic
is true with:Post.objects.filter(public=True)
Update the view function so only public posts are displayed on your homepage. Use the admin interface to make some posts private and confirm they are no longer visible.
-
If the body of a post contains multiple lines, the line breaks will not be visible on our homepage because HTML is whitespace insensitive. Fix this by ensuring line break tags are inserted into our HTML by applying the
linebreaks
filter to ourpost.body
:{{ post.body | linebreaks }}
-
In your browser, right-click on the page and choose View Page Source to see the actual HTML generated by the template.