Templates

View saved

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.