Learn Flask SQLAlchemy by Building a To-Do List Application
Building a to-do list application is a classic way to learn the fundamentals of web development. Adding a persistent database backend elevates this learning experience, introducing crucial concepts like data modeling, querying, and database interactions. This article provides a comprehensive guide to building a to-do list application using Flask and SQLAlchemy, a powerful Python SQL toolkit and Object Relational Mapper (ORM). We’ll cover everything from setting up the project to implementing advanced features like user authentication and task prioritization.
Part 1: Setting Up the Environment and Project Structure
Before we begin, ensure you have Python 3 installed. We’ll use a virtual environment to isolate our project dependencies.
- Create a virtual environment:
bash
python3 -m venv venv
- Activate the virtual environment:
bash
source venv/bin/activate # On Linux/macOS
venv\Scripts\activate # On Windows
- Install required packages:
bash
pip install Flask Flask-SQLAlchemy Flask-WTF WTForms
- Create the project structure:
todo_app/
├── app.py
├── models.py
├── forms.py
├── templates/
│ └── index.html
└── static/
└── style.css
Part 2: Defining the Data Model with SQLAlchemy
Our to-do list application will store tasks, each with a description, a due date, a priority level, and a completion status. Let’s define the Task
model in models.py
:
“`python
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Task(db.Model):
id = db.Column(db.Integer, primary_key=True)
description = db.Column(db.String(200), nullable=False)
due_date = db.Column(db.Date)
priority = db.Column(db.Integer, default=1) # 1 being lowest, 3 being highest
completed = db.Column(db.Boolean, default=False)
def __repr__(self):
return f'<Task {self.id}: {self.description}>'
“`
Part 3: Creating the Flask Application and Database Connection
Now, let’s create the Flask application and connect it to our database in app.py
:
“`python
from flask import Flask, render_template, request, redirect, url_for
from models import db, Task
from forms import TaskForm
import os
app = Flask(name)
app.config[‘SECRET_KEY’] = os.urandom(24) # Generate a random secret key
app.config[‘SQLALCHEMY_DATABASE_URI’] = ‘sqlite:///todo.db’ # Use SQLite for simplicity
app.config[‘SQLALCHEMY_TRACK_MODIFICATIONS’] = False
db.init_app(app)
with app.app_context():
db.create_all()
… (routes will be added here later) …
if name == ‘main‘:
app.run(debug=True)
“`
Part 4: Creating Forms with WTForms
We’ll use WTForms to create a form for adding and editing tasks. Create forms.py
:
“`python
from wtforms import StringField, DateField, IntegerField, BooleanField, SubmitField
from wtforms.validators import DataRequired, Length
class TaskForm(Form):
description = StringField(‘Description’, validators=[DataRequired(), Length(max=200)])
due_date = DateField(‘Due Date’)
priority = IntegerField(‘Priority’, default=1)
submit = SubmitField(‘Add Task’)
“`
Part 5: Implementing Routes and Views
Let’s add routes to handle displaying the to-do list, adding new tasks, marking tasks as complete, and deleting tasks. Update app.py
:
“`python
… (previous code from app.py) …
@app.route(‘/’, methods=[‘GET’, ‘POST’])
def index():
form = TaskForm()
if form.validate_on_submit():
task = Task(description=form.description.data, due_date=form.due_date.data, priority=form.priority.data)
db.session.add(task)
db.session.commit()
return redirect(url_for(‘index’))
tasks = Task.query.order_by(Task.due_date).all()
return render_template(‘index.html’, tasks=tasks, form=form)
@app.route(‘/complete/
def complete_task(task_id):
task = Task.query.get_or_404(task_id)
task.completed = True
db.session.commit()
return redirect(url_for(‘index’))
@app.route(‘/delete/
def delete_task(task_id):
task = Task.query.get_or_404(task_id)
db.session.delete(task)
db.session.commit()
return redirect(url_for(‘index’))
… (rest of the app.py code) …
“`
Part 6: Creating the Template
Finally, let’s create the index.html
template:
“`html
My To-Do List
-
{% for task in tasks %}
-
{% if task.completed %}
{% endif %}{% endif %}
{{ task.description }} – Due: {{ task.due_date.strftime(‘%Y-%m-%d’) }}, Priority: {{ task.priority }}
{% if task.completed %}
Complete
Delete
{% endfor %}
“`
Part 7: Adding Styling (Optional)
Create a simple style.css
file in the static
folder to enhance the appearance of the to-do list.
Part 8: Further Enhancements
This is a basic to-do list application. You can expand upon this foundation by adding features like:
- User authentication: Allow users to create accounts and manage their own to-do lists. Consider using Flask-Login.
- Task editing: Implement functionality to edit existing tasks.
- Search and filtering: Allow users to search for specific tasks or filter by due date, priority, or completion status.
- Data validation: Implement more robust data validation using WTForms validators.
- Advanced styling: Use a CSS framework like Bootstrap to improve the visual appeal.
- Asynchronous updates: Use JavaScript and AJAX to update the to-do list without requiring page reloads.
- API integration: Create an API to interact with the to-do list from other applications.
This detailed guide provides a solid foundation for building a functional to-do list application with Flask and SQLAlchemy. By understanding the core concepts presented here, you can further customize and expand the application to suit your specific needs and explore more advanced web development techniques. Remember to consult the Flask and SQLAlchemy documentation for more in-depth information and advanced features. By building this application, you’ll gain practical experience with database interactions, data modeling, and web development best practices, empowering you to create more complex and dynamic web applications in the future. Remember to test thoroughly after each step to identify and fix any issues early on. Happy coding!