Introduction
In Python we learn few datastructures such as tuple, list, dictionary.
Flask as Python web framework has it’s own way to handle Python datastructures. In this tutorial is a guide how to iterate through Python datastructures using Flask for:
- list
- dictionary
- list in dictionary
Create a file structure:
+ app.py
+ templates/
+ index.html
+ virtual/
Above got two folders which templates has index.html while virtual is a Python virtual environment ready for activation. app.py in a root directory to code Flask-Python script.
For a start let’s activate it by running the command in the terminal.
$ source virtual/bin/activate
Next, we are going to create a basic Flask app with app.py which is .py extension.
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "Hello World!"
if __name__ == "__main__":
app.run(debug=True)
app.py
app.py is the minimal or barebone Flask script to run in localhost webserver.
Below the index.html ready script for you to copy and paste and follow along this tutorial.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>This is index page</title>
<link rel="stylesheet" type="text/css" href="style.css">
<style>
body {
background-color: white;
}
h2, h3 {
text-align: center;
}
table {
margin-left: auto;
margin-right: auto;
}
.container {
padding: 20px;
width: 800px;
background-color: #eee;
margin-left: auto;
margin-right: auto;
}
td {
text-align: center;
}
</style>
</head>
<body>
<!-- your content here... -->
<h2>This is index page</h2>
<div class="container">
</div>
</body>
</html>
index.html
However if you run this page in the internet browser it is unavailable.
To enable this there are few steps that need to be done.
- import render_template in
app.pyscript. - then add
render templatecommand
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def index():
return render_template('index.html')
if __name__ == "__main__":
app.run(debug=True)
Run in terminal
$ python app.py
Browse and type in your url link web browser either
- 127.0.0.1:5000 or
- localhost:5000 or
- 0.0.0.0:5000
Any above of these ip address either 127.0.0.1 or localhost or 0.0.0.0 will refer to the same Flask web application port number 5000 local web machine in your computer.
In coding it’s easier to describe using Python syntax
127.0.0.1 == localhost == 0.0.0.0
Once it has text printed This is an index page means that it’s correctly loaded.
It’s about time to let app.py handle the business logic while index.html to do the markup language or styling.
Let me think what if I would like to assign a title to variable using Python.
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
# localhost:5000
@app.route('/index')
# localhost:5000/index
def index():
greet = 'Flask-Python | How to Iterate in List, Dictionary and list in Dictionary'
return render_template("index.html", greet=greet)
if __name__ == '__main__':
app.run(debug=True)
Created above greet as variable assigned to text or strings. Then added into the parameter after index.html separated by comma. As the parameter greet=greet the first greet must be the same as in index.html.
If you decide to change from greet to something like abc_something then it will be like this abc_something=greet. The abc_something will be used by Jinja in index.html.
To enable this in index.html by using Jinja which start with { and end with }.
Inside index.html below the body and h2 tag let’s add another h2 tag using Jinja to insert greet variable as below.
<body>
<h2>This is index page</h2>
<h2>{{ greet }}</h2>
Above { greet } it displays the variable input into the browser that fetch from app.py script. You can either refresh the page or run in terminal with this command
$ python app.py
Here is what it’s look like in the screen splitted into two panes side by side.
I think you could have grasp the basic on how to call Python variable to html page. Next let’s iterate list as Python data and display as row table in html as below.
Iterate-list-Flask
To iterate a list of data in Flask.
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
# localhost:5000
@app.route('/index')
# localhost:5000/index
def index():
greet = 'Flask-Python | How to Iterate in List, Dictionary and list in Dictionary'
months = ['Jan', 'Feb', 'March']
return render_template("index.html", greet=greet, months=months)
if __name__ == '__main__':
app.run(debug=True)
Below after variable greet added months as list and iterate for each of the month.
- put in the parameter inside
render_templatewithmonths=months.monthsassign asmonthsbefore it used inindex.html.
Let’s iterate this in html page.
<div class="container">
<table>
<thead>
<tr>
<th>Month</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ "loop data here..." }}</td>
</tr>
</tbody>
</table>
Inside container div tag created a table split by two which is thead and tbody.
- For each
theadandtbodyhastras a row. trinsidetheadconsists ofthrepresents header whiletrinsidetbodyhastdas data looping.- In between
thadd a label name asMonthwhile fortdtags here is a line ofjinjawith a string:
{{ "loop data here…" }}
<table>
<thead>
<tr>
<th>Month</th>
</tr>
</thead>
{% for month in months %}
<tbody>
<tr>
<td> {{ month }} </td>
</tr>
</tbody>
{% endfor %}
</table>
index.html
As you can see above we start for loop using jinja by open before tbody tag
{% for month in months %}
and closed after /tbody tag with
{% endfor %}
Then we replace string loop data here.. with month as variable as below
{{ month }}
This will iterate each month of the months as list use in Python.
Next, let’s enumerate each month using jinja version.
<table>
<thead>
<tr>
<th>No</th>
<th>Month</th>
</tr>
</thead>
{% for month in months %}
<tbody>
<tr>
<td> {{ loop.index }} </td>
<td> {{ month }} </td>
</tr>
</tbody>
{% endfor %}
</table>
index.html
To enumerate is by code two simple steps
- 1st create a column in
theadrow and in betweenthtags we add a label nameNo. - 2nd create a column in
tbodyrow and in betweentdtags add usingjinjaas below
{{ loop.index }}
Iterate-dictionary-Flask
Dictionary is a datastructure that pairs between key and values.
Next data is pair of grades for each subjects.
def index():
greet = 'Flask-Python | How to Iterate in List, Dictionary and list in Dictionary'
months = ['Jan', 'Feb', 'March']
grades = {'Psychology': 'A+', 'Mathematics': 'B','English Literature': 'B+', 'Economics': 'C'}
return render_template("index.html", greet=greet, months=months, grades=grades)
app.py
Here got grades a Python dictionary and assign grades to a variable name as grades too as parameter.
Display grades in index.html has almost the same procedure like list except for some additional loop.
Create a new grades table of dictionary to separate from the previous list table for months.
<table>
<thead>
<tr>
<th>No</th>
<th>Subject</th>
<th>Grade</th>
</tr>
</thead>
<tbody>
{% for key, value in grades.items() %}
<tr>
<td>{{ loop.index }}</td>
<td>{{key}}</td>
<td>{{value}}</td>
</tr>
{% endfor %}
</tbody>
</table>
index.html
A table for grades a dictionary data type that has thead for label and tbody to loop between key and value.
gradeshas two elements which iskeythe name of subjects and thevalueagradefor each subject.- There are two labels
SubjectandGradeinthoftrintothead. Add another label to count for each of the row for both columngradesand name asNo. Labels here can be refer as column with name. - While between
/theadandtbodyadded afor loopopening and closingfor loopafter/tbodytag. Here is what it looks like. - Below shows an opening loop syntax
for .. in …
- Next need to close the loop syntax
endfor
</thead>
{% for x in grades %}
<tbody>
<!-- got some code here ... -->
</tbody>
{% endfor %}
Assign x to loop grades. x will specify both key for subject and value for each subject grade either A+, B or anything similar.
To enable looping for subject and grade I add another for loop as Python dictionary.
{% for x in grades %}
<tbody>
{% for key, value in x.items() %}
<tr>
<td>{{ loop.index }}</td>
<td>{{key}}</td>
<td>{{value}}</td>
</tr>
{% endfor %}
</tbody>
{% endfor %}
- Added another loop inside the existing
gradesto specifysubjectandgradethroughx.items()
for key, value in x.items()
- Don’t forget to close the loop
endfor
- Let’s loop inside
trtags create each loop fortdopen and close tag. Got three values that includesloop.indexbesideskeythat refer tosubjectandvaluerefer tograde. You may changekeyandvalueto whatever name you prefer but I will stick to these names for this tutorial.
Iterate-list-in-dictionary-Flask
Our final data is a combination of list and dictionary. Inside dictionary has a key and multiples values.
Below example is data for BMI an acronym for Body-Mass-Index.
def index():
greet = 'Flask-Python | How to Iterate in List, Dictionary and list in Dictionary'
months = ['Jan', 'Feb', 'March']
grades = [{'Psychology': 'A+', 'Mathematics': 'B','English Literature': 'B+', 'Economics': 'C'}]
bmi_records = {'jack': [150, 60, 'male'],
'bob': [173, 83, 'male'],
'jane': [153, 54, 'female']}
return render_template("index.html", greet=greet, months=months, grades=grades, bmi_records=bmi_records)
if __name__ == '__main__':
app.run(debug=True)
app.py
bmi_records shows key name of participants and value inside list [] with multiples data start with height (cm) follow by weight (kg) and last one is gender either male or female.
Assigned both bmi_records=bmi_records inside render_template parameter to tell index.html that this is a variable that holds data using Python.
Move to the step calling from index.html
<table>
<thead>
<tr>
<th>No</th>
<th>Name</th>
<th>Height (kg)</th>
<th>Weight (cm)</th>
<th>Gender</th>
</tr>
</thead>
<!-- got some code here ... -->
</table>
Created another table to iterate bmi_records. Under thead and tr added five labels No, Name, Height (kg), Weight (cm) and Gender as th tag for each.
<table>
<thead>
<tr>
<th>No</th>
<th>Name</th>
<th>Height (kg)</th>
<th>Weight (cm)</th>
<th>Gender</th>
</tr>
</thead>
{% for key, value in bmi_records.items() %}
<tbody>
<tr>
</tr>
</tbody>
{% endfor %}
</table>
There are two for loops. Start with for x in bmi_record before tbody tag and end after /tbody tag with endfor.
Next another for loop to specify between key and value after tbody tag and end the loop endfor before /tbody tag inside the current loop of bmi_records by specifying x.items().
<tbody>
{% for key, value in x.items() %}
<tr>
<td>{{ loop.index }}-</td>
<td>{{key}}</td>
<td>{{value[0]}}</td>
<td>{{value[1]}}</td>
<td>{{value[2]}}</td>
</tr>
{% endfor %}
</tbody>
loop.index is the enumerate or counter for each row of data loop.
Next loop into each key refer as name while values a Python list that has three datatypes which is height (cm) refer as value[0], height (kg) refer as value[1] and gender either male or female as value[2]. The numbers for each value as Python list datatype index from 0 and follow the subsequent.
An important note to remember in dictionary a value can only has one key only while a key can has multiple values.
################
Here is the final sourcecode
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
# localhost:5000
@app.route('/index')
# localhost:5000/index
def index():
greet = 'Flask-Python | How to Iterate in List, Dictionary and list in Dictionary'
months = ['Jan', 'Feb', 'March']
grades = [{'Psychology': 'A+', 'Mathematics': 'B','English Literature': 'B+', 'Economics': 'C'}]
bmi_records = [{'jack': [150, 60, 'male'],
'bob': [173, 83, 'male'],
'jane': [153, 54, 'female']}]
return render_template("index.html", greet=greet, months=months, grades=grades, bmi_records=bmi_records)
if __name__ == '__main__':
app.run(debug=True)
app.py
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Flask CRUD-App with SQLite3</title>
<link rel="stylesheet" type="text/css" href="style.css">
<style>
body {
background-color: white;
}
h2, h3 {
text-align: center;
}
table {
margin-left: auto;
margin-right: auto;
}
.container {
padding: 20px;
width: 800px;
background-color: #eee;
margin-left: auto;
margin-right: auto;
}
</style>
</head>
<body>
<h2>This is index page</h2>
<h2>{{ greet }}</h2>
<div class="container">
<table>
<thead>
<tr>
<th>No</th>
<th>Month</th>
</tr>
</thead>
{% for month in months %}
<tbody>
<tr>
<td>{{ loop.index }}</td>
<td> {{ month }} </td>
</tr>
</tbody>
{% endfor %}
</table>
<table>
<thead>
<tr>
<th>No</th>
<th>Subject</th>
<th>Grade</th>
</tr>
</thead>
{% for x in grades %}
<tbody>
{% for key, value in x.items() %}
<tr>
<td>{{ loop.index }}</td>
<td>{{key}}</td>
<td>{{value}}</td>
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
<table>
<thead>
<tr>
<th>No</th>
<th>Name</th>
<th>Height (kg)</th>
<th>Weight (cm)</th>
<th>Gender</th>
</tr>
</thead>
{% for x in bmi_records %}
<tbody>
{% for key, value in x.items() %}
<tr>
<td>{{ loop.index }}-</td>
<td>{{key}}</td>
<td>{{value[0]}}</td>
<td>{{value[1]}}</td>
<td>{{value[2]}}</td>
</tr>
{% endfor %}
</tbody>
{% endfor %}
</table>
</div>
<!-- your content here... -->
</body>
</html>
index.html