List Todos Template¶
We’ll convert another view to use a view template with a master template. In the process, we’ll get our first real use of the debugger by setting a breakpoint in the template.
Steps¶
Let’s make a template in
templates/list_todos.html
:{% extends "layout.html" %} {% block content %} <ul> {% for todo in todos %} <li> <a href="/todo/{{ todo.id }}">{{ todo.title }}</a> </li> {% endfor %} </ul> {% endblock %}
In
app.py
, change thelist_todos
, making it much simpler: it just hands data to the template:def list_todos(): todos = Todo.list() return render_template('list_todos.html', page_title='List Todos', todos=todos)
Note: The page_title mistake is intentional.
Next, let’s do the same for
show_todo
. First, createtemplates/show_todo.html
:{% extends "layout.html" %} {% block content %} <p>{{ todo.title }}</p> {% endblock %}
In
app.py
, change theshow_todo
, also making it much simpler: it just hands data to the template:def show_todo(todo_id): todo = Todo.get_id(todo_id) return render_template('show_todo.html', title='Todo ' + str(todo_id), todo=todo)
Note: PyCharm Professional autocompletes the template filename from the ``templates`` directory, which is very helpful.
In your browser, visit the
List Todos
page. We aren’t getting atitle
displayed. Let’s debug it.Open
templates/layout.html
and click in the left margin on the second line, where<head><title>
occurs. Your click should create a red circle for a “breakpoint”.Reload your browser. PyCharm switches back in view, with the execution “stopped” on that line.
Look in the “Variables” window at the bottom. You see all the Python values defined at that point in the template. You realize
title
isn’t there, butpage_title
is, thus your error.In the Debug Tool window, click the green arrow play button to “Resume Program”.
In
app.py
, changepage_title
totitle
.Reload the browser and execution again stops in that place. Confirm that a
title
variable exists and click the green arrow again to Resume Program.Now, the browser provides the List Todos heading.
Click the red circle to clear the breakpoint.
Let’s set a breakpoint in the loop. In
list_todos.html
, click in the left margin on the<a>
in the<li>
.Reload the browser. When execution stops, in the
Variables
pane, note thattodo
is defined. Expand it to see what information it contains.Your
app.py
should match the following:from flask import Flask from flask import render_template from models import populate_todos, Todo app = Flask(__name__) @app.route('/') def home_page(): return render_template('home_page.html', title='Home Page') @app.route('/todo/') def list_todos(): todos = Todo.list() return render_template('list_todos.html', title='List Todos', todos=todos) @app.route('/todo/<int:todo_id>') def show_todo(todo_id): todo = Todo.get_id(todo_id) return render_template('show_todo.html', title='Todo ' + str(todo_id), todo=todo) if __name__ == '__main__': populate_todos() app.run(debug=True)
Your
templates/list_todos.html
should match the following:{% extends "layout.html" %} {% block content %} <ul> {% for todo in todos %} <li> <a href="/todo/{{ todo.id }}">{{ todo.title }}</a> </li> {% endfor %} </ul> {% endblock %}
Your
templates/show_todo.html
should match the following:{% extends "layout.html" %} {% block content %} <p>{{ todo.title }}</p> {% endblock %}
- Previous topic: Master Template
- Next topic: Sorted Todos Template