Create a Web-Based Habit Tracker with Python and Flask
Tracking habits is a great way to maintain and build consistency in your daily life. In this blog post, we will build a simple web-based habit tracker using Python's Flask web framework. This application will allow users to create, track, and manage their habits. We’ll use SQLite as our database and Bootstrap for a responsive and user-friendly interface.
1. Prerequisites
Before we start, make sure you have the following installed on your machine:
Python (>=3.8)
pip (Python package installer)
Basic knowledge of Flask and HTML/CSS
2. Setting Up the Project
First, let's create a new directory for our project and set up a virtual environment.
# Create a new directory for the habit tracker
mkdir flask_habit_tracker
cd flask_habit_tracker
# Set up a virtual environment
python -m venv venv
source venv/bin/activate # On Windows use `venv\Scripts\activate`
# Install Flask
pip install Flask
3. Creating the Flask App Structure
Let's create a basic structure for our Flask application:
flask_habit_tracker/
│
├── app/
│ ├── __init__.py
│ ├── routes.py
│ ├── models.py
│ └── templates/
│ ├── layout.html
│ ├── index.html
│ └── add_habit.html
├── static/
│ ├── css/
│ │ └── style.css
│ └── js/
│ └── script.js
├── venv/
└── run.py
File Descriptions:
__init__.py
: Initialize the Flask app.routes.py
: Contains all the URL routes for our app.models.py
: Defines our database models.templates/
: Contains HTML templates.static/
: Contains static files like CSS and JavaScript.
4. Designing the Database
We will use SQLite for this project. Let’s define our habit model in models.py
:
# app/models.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Habit(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
description = db.Column(db.String(200))
streak = db.Column(db.Integer, default=0)
last_completed = db.Column(db.Date)
5. Developing the Habit Tracker Functionality
Next, we need to set up our Flask app and create the routes in routes.py
.
Initialize the Flask App in __init__.py
:
# app/__init__.py
from flask import Flask
from .models import db
def create_app():
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///habits.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
with app.app_context():
db.create_all()
from .routes import main
app.register_blueprint(main)
return app
Define Routes in routes.py
:
# app/routes.py
from flask import Blueprint, render_template, request, redirect, url_for
from datetime import datetime
from .models import db, Habit
main = Blueprint('main', __name__)
@main.route('/')
def index():
habits = Habit.query.all()
return render_template('index.html', habits=habits)
@main.route('/add', methods=['GET', 'POST'])
def add_habit():
if request.method == 'POST':
name = request.form['name']
description = request.form['description']
new_habit = Habit(name=name, description=description)
db.session.add(new_habit)
db.session.commit()
return redirect(url_for('main.index'))
return render_template('add_habit.html')
6. Creating Templates with Bootstrap
Let's create our HTML templates using Bootstrap for a clean, responsive design.
layout.html (Base Template):
<!-- app/templates/layout.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Habit Tracker</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
{% block content %}
{% endblock %}
</div>
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
</body>
</html>
index.html (Main Page):
<!-- app/templates/index.html -->
{% extends 'layout.html' %}
{% block content %}
<h1 class="mt-5">Habit Tracker</h1>
<a href="{{ url_for('main.add_habit') }}" class="btn btn-primary">Add New Habit</a>
<hr>
<table class="table mt-3">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Streak</th>
<th>Last Completed</th>
</tr>
</thead>
<tbody>
{% for habit in habits %}
<tr>
<td>{{ habit.name }}</td>
<td>{{ habit.description }}</td>
<td>{{ habit.streak }}</td>
<td>{{ habit.last_completed }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
add_habit.html (Form to Add New Habit):
<!-- app/templates/add_habit.html -->
{% extends 'layout.html' %}
{% block content %}
<h2 class="mt-5">Add a New Habit</h2>
<form method="POST" class="mt-3">
<div class="mb-3">
<label for="name" class="form-label">Habit Name</label>
<input type="text" class="form-control" id="name" name="name" required>
</div>
<div class="mb-3">
<label for="description" class="form-label">Description</label>
<input type="text" class="form-control" id="description" name="description">
</div>
<button type="submit" class="btn btn-primary">Add Habit</button>
</form>
{% endblock %}
7. Testing and Running the Application
Run the Flask Application:
In your run.py
file, add the following code:
# run.py
from app import create_app
app = create_app()
if __name__ == '__main__':
app.run(debug=True)
Run your application with:
python run.py
Open your browser and navigate to http://127.0.0.1:5000/
to see your Habit Tracker in action!
8. Deploying the Application
To deploy the application, consider using platforms like Heroku, PythonAnywhere, or AWS. Make sure to configure the environment variables and database settings according to the platform requirements.
Conclusion
Subscribe to my newsletter
Read articles from ByteScrum Technologies directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
ByteScrum Technologies
ByteScrum Technologies
Our company comprises seasoned professionals, each an expert in their field. Customer satisfaction is our top priority, exceeding clients' needs. We ensure competitive pricing and quality in web and mobile development without compromise.