# 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](https://bytescrum.com/) 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 (&gt;=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.

```bash
# 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:

```plaintext
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`](http://routes.py): Contains all the URL routes for our app.
    
* [`models.py`](http://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`](http://models.py):

```python
# 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`:

```python
# 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`:

```python
# 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):

```xml
<!-- 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):

```xml
<!-- 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):

```xml
<!-- 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`](http://run.py) file, add the following code:

```python
# run.py

from app import create_app

app = create_app()

if __name__ == '__main__':
    app.run(debug=True)
```

Run your application with:

```bash
python run.py
```

Open your browser and navigate to [`http://127.0.0.1:5000/`](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.

<details data-node-type="hn-details-summary"><summary>Conclusion</summary><div data-type="detailsContent">Congratulations! You've built a simple web-based habit tracker using Python, Flask, SQLite, and Bootstrap. This app can be easily extended to add more features like user authentication, habit reminders, and detailed statistics to help users stay motivated. Feel free to customize the code, add new features, and improve the user experience. Happy coding!</div></details>
