Templates
Goal for this part
Replace bare HttpResponse strings with real HTML pages. You will use Django templates, a shared base.html layout, static CSS, and two pages: a home feed and an about page.
After this snapshot, Campus Press should look like a small website instead of plain text in the browser.
What you should already know
Comfort with the home and about routes from the previous part is enough. Basic HTML familiarity helps; you do not need prior Jinja or Django template experience.
Django’s template language looks similar to other systems: variables in {{ }}, tags like {% extends %} and {% block %} for layout reuse.
Concepts: template inheritance and static files
A base template defines the chrome—nav, footer, CSS link—and child templates fill named blocks. That keeps every page consistent without copy-pasting the whole document.
Static files (CSS, images) live under an app or project static directory. In templates, {% load static %} and {% static 'blog/main.css' %} resolve the correct URL in development.
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="{% static 'blog/main.css' %}">
<title>Campus Press — {% block title %}Home{% endblock %}</title>
</head>
<body>
<nav>...</nav>
<main>{% block content %}{% endblock %}</main>
</body>
</html>
Walkthrough: render_template and context
Views call render(request, "blog/home.html", context) instead of returning raw strings. Context is a dictionary of values the template can print—for now, a short list of sample posts.
Place templates under blog/templates/blog/ so Django’s app directories loader finds them. Namespacing the folder as blog/ avoids clashes when several apps define home.html.
from django.shortcuts import render
posts = [
{"author": "Ada", "title": "Welcome", "content": "First post."},
{"author": "Grace", "title": "Routing", "content": "URLs and views."},
]
def home(request):
return render(request, "blog/home.html", {"posts": posts})
def about(request):
return render(request, "blog/about.html", {"title": "About"})
How to run it and what you should see
Start the 03-Templates snapshot. Home should list sample posts inside a shared layout; About should use the same nav and styles. If CSS is missing, confirm {% load static %} and the static path.
git clone https://github.com/michaeldunga1/fcc-django-blog.git
cd fcc-django-blog/03-Templates
python3 -m venv .venv
source .venv/bin/activate
pip install -r ../requirements.txt
python manage.py runserver
Common mistakes and troubleshooting
TemplateDoesNotExist usually means the file path or app templates folder layout is wrong. Static 404s often mean a missing {% load static %}, a typo in the static path, or the server started before the CSS file was saved.
If navigation links 404, prefer {% url 'blog-home' %} over hard-coded hrefs so renames stay in one place.
Try this
Add a third sample post to the list and refresh. Then change a color in main.css and hard-refresh the browser so you can see static files update.
- Extend a base template; fill blocks in child pages
- Pass context from the view; print it with
{{ }} - Keep CSS in static files, not inline forever
Next: Models and Admin
Comments
One comment per signed-in account. Comments are saved with this page’s URL.