Computing Society: Session 5+6 Flask intro and Database
Session 5+6: Flask Introduction and Advanced Concepts
5.1 Environment Setup and Dependency Installation (5 minutes)
- Setup:
- 🛠️ Install Flask and Flask-SQLAlchemy:
1
pip install flask flask-sqlalchemy
- ✅ Verify Installation:
- Run this sample
app.py
to confirm everything works:1
2
3
4
5
6
7
8
9from flask import Flask
app = Flask(__name__)
def hello():
return "Hello, World!"
if __name__ == '__main__':
app.run(debug=True)
- Run this sample
- 🛠️ Install Flask and Flask-SQLAlchemy:
5.2 Routing in Flask (20 minutes)
Basic Routing Syntax:
- 🌐 Concept: Routing links each URL to a function in Flask.
- 📌 Basic Route Example:
1
2
3
def home():
return "Welcome to the Sports App!"
Advanced Routing:
- 🔀 Capturing URL Parameters:
- Syntax for dynamic routes, e.g.,
<int:id>
or<string:name>
. - Example Task: Create routes like
/team/<int:team_id>
for specific team details.1
2
3
def show_team(team_id):
return f"Details for Team {team_id}"
- Syntax for dynamic routes, e.g.,
- 🛑 Custom Error Handling:
- Define error routes for user-friendly error messages:
1
2
3
def page_not_found(e):
return "Page not found. Please check the URL.", 404
- Define error routes for user-friendly error messages:
- 🔀 Capturing URL Parameters:
5.3 Template Rendering with Jinja2 and HTML Basics (25 minutes)
Basic Template and HTML Syntax:
📝 Concept: Use templates to render dynamic HTML.
💡 HTML Basics:
- Create a simple
greet.html
template:1
2
3
4
5
6
7
8
9
<html lang="en">
<head>
<title>Sports App</title>
</head>
<body>
<h1>Welcome, {{ name }}!</h1>
</body>
</html>
- Create a simple
Rendering in Flask:
- Example:
1
2
3
4
5from flask import render_template
def greet(name):
return render_template('greet.html', name=name)
- Example:
Advanced Template Rendering:
🔄 Loops and Conditionals:
- Use
for
loops to iterate over lists andif
statements for conditional content. - Example Task: Create a list of teams and display them in an HTML table.
1
2
3
4
5<ul>
{% for team in teams %}
<li>{{ team.name }} - {{ team.points }} points</li>
{% endfor %}
</ul>
- Use
Filters:
- ✨ Transform Text:
1
2<p>{{ team.name|upper }}</p> <!-- Displays name in uppercase -->
<p>Teams Count: {{ teams|length }}</p>
- ✨ Transform Text:
5.4 Introduction to Forms in Flask (30 minutes)
HTML Forms:
📋 Basic Form Example:
- Create a simple HTML form to collect user data:
1
2
3
4
5<form action="/submit" method="POST">
<label for="teamName">Team Name:</label>
<input type="text" id="teamName" name="teamName" required>
<button type="submit">Submit</button>
</form>
- Create a simple HTML form to collect user data:
Handling Form Data in Flask:
- Example route to handle form submission:
1
2
3
4
5
6from flask import request
def submit():
team_name = request.form['teamName']
return f"Team {team_name} has been added!"
- Example route to handle form submission:
Flask-WTF for Forms:
📦 Installing Flask-WTF:
1
pip install flask-wtf
📝 Creating a Form Class:
- Example of using Flask-WTF:
1
2
3
4
5
6
7from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired
class TeamForm(FlaskForm):
team_name = StringField('Team Name', validators=[DataRequired()])
submit = SubmitField('Submit')
- Example of using Flask-WTF:
Rendering Flask-WTF Forms:
- Example route with a Flask-WTF form:
1
2
3
4
5
6
7
8
9
10from flask import render_template
from forms import TeamForm # Assume forms.py contains the TeamForm class
def add_team():
form = TeamForm()
if form.validate_on_submit():
team_name = form.team_name.data
return f"Team {team_name} has been added!"
return render_template('add_team.html', form=form)
- Example route with a Flask-WTF form:
Creating the Template:
- Create
add_team.html
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html lang="en">
<head>
<title>Add Team</title>
</head>
<body>
<h1>Add a New Team</h1>
<form method="POST">
{{ form.hidden_tag() }}
{{ form.team_name.label }} {{ form.team_name() }}
{{ form.submit() }}
</form>
</body>
</html>
- Create
5.5 Database Integration with SQLite and Flask-SQLAlchemy (20 minutes)
- Setting Up the Database and Model:
- 🗄️ Define Models with SQLAlchemy:
- Example
Team
model:1
2
3
4
5
6
7
8
9
10
11
12
13
14from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///sports.db'
db = SQLAlchemy(app)
class Team(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False)
points = db.Column(db.Integer, default=0)
with app.app_context():
db.create_all()
- Example
- 🗄️ Define Models with SQLAlchemy:
- Basic CRUD Operations:
- 🔄 Add Data:
1
2
3new_team = Team(name="Lions", points=55)
db.session.add(new_team)
db.session.commit() - 👀 Retrieve Data:
1
teams = Team.query.all()
- Display Data:
- Example Route:
1
2
3
4
def leaderboard():
teams = Team.query.order_by(Team.points.desc()).limit(3).all()
return render_template('leaderboard.html', teams=teams)
- Example Route:
- 🔄 Add Data:
5.6 Graph Data Structure and SQL Relation (Tree Example) (10 minutes)
Graph Theory Basics:
- 🌳 Competition Bracket as a Tree Structure:
- Represents hierarchical data with parent-child relationships.
- 🌳 Competition Bracket as a Tree Structure:
Tree Structure in Python with SQLAlchemy:
- 🔗 Defining Parent-Child Relationships:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
class Match(db.Model):
match_id = db.Column(db.Integer, primary_key=True)
team1_id = db.Column(db.Integer, db.ForeignKey('team.id'), nullable=False)
team2_id = db.Column(db.Integer, db.ForeignKey('team.id'), nullable=False)
winner_id = db.Column(db.Integer, db.ForeignKey('team.id'), nullable=True)
team1 = db.relationship('Team', foreign_keys=[team1_id])
team2 = db.relationship('Team', foreign_keys=[team2_id])
winner = db.relationship('Team', foreign_keys=[winner_id])
# Sample entry
match = Match(team1_id=1, team2_id=2, winner_id=1)
db.session.add(match)
db.session.commit() - Query Example: Fetch teams advancing in each round by querying the
winner_id
field.1
2
3
4# Retrieve all matches with determined winners
matches = Match.query.filter(Match.winner_id.isnot(None)).all()
for match in matches:
print(f"Match {match.match_id}: Winner - Team {match.winner_id}")
- 🔗 Defining Parent-Child Relationships:
Tree Structure in SQL:
- 🔗 Parent-Child Relationships:
1
2
3
4
5
6
7
8
9CREATE TABLE matches (
match_id INTEGER PRIMARY KEY,
team1_id INTEGER,
team2_id INTEGER,
winner_id INTEGER,
FOREIGN KEY (team1_id) REFERENCES Team(id),
FOREIGN KEY (team2_id) REFERENCES Team(id),
FOREIGN KEY (winner_id) REFERENCES Team(id)
); - Query: Fetch teams by bracket round:
1
SELECT * FROM matches WHERE winner_id IS NOT NULL;
- 🔗 Parent-Child Relationships: