Building a Flask todo web application from scratch
Tags: webdev, beginners, python, tutorial
Published: 2024-01-29 14:22:59

### Introduction

Welcome 👋 to this blog. If you want to build a `todo` web application with the help of **Flask** then you are in the correct blog. This tutorial will build a [Flask](https://flask.palletsprojects.com/en/3.0.x/) todo web application completely from scratch. Let's start building the web application. One more thing at the end you will also get the GitHub repository link as well so you can only focus on concepts.

### Project Structure

- Let's create a new folder with the name todo-app(anything you want).
- The file structure should look like this.
```
/flask-todos
    app.py
    /static
        *.css
        *.js
        *.png
        all static files
    /templates
        index.html
        *.html
        your HTML files
```
Here, the `static` folder will contain the static files(CSS, js, images, etc.), `templates` will contain all the HTML files & `app.py` is the Flask backend file that handles the request from the client and also communicates with the database.

### Client-Server Architecture

![client-server-architecture-image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gxlkdbqyr60vrpiu2gvj.png)

Assume the `client` is the **user**, the `server` is the **remote Operating System** where your business logic code is written & `database` is a **remote hard disk** that you can access from anywhere. But we are simulating all three on our local computer for the development which is fine.

### index.html
This is the **initial** code of the `index.html` file. This code contains the basic structure of the web page. I am using [Bootstrap](https://getbootstrap.com/).

```HTML
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
    <link rel="stylesheet" href="/static/index.css">
  </head>
  <body>
    <div class="container mt-5 mb-5">
        <h3 class="mt-5 mb-5">Todo Web Application</h3>
        <form action="/" method="POST">
            <div class="row">
                <div class="col">
                    <div class="mb-3">
                        <label for="title" class="form-label">Title</label>
                        <input type="text" class="form-control" name="title" id="title">
                    </div>
                </div>
                <div class="col">
                    <div class="mb-3">
                        <label for="content" class="form-label">Content</label>
                        <input type="text" class="form-control" name="content" id="content">
                    </div>
                </div>
            </div>
            <button type="submit" class="btn btn-warning">Submit</button>
          </form>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
  </body>
</html>
```

### index.css 
This file contains no CSS for this project. But feel free to add your custom CSS according to your choice.

### app.py
This is a very important file for our project. This helps us to connect with the SQL databases as well as _serve the client request_. 

Breakdown of the file code.
- Initially, we are importing all the necessary libraries. (e.g., Flask, [sql_alchemy](https://flask-sqlalchemy.palletsprojects.com/en/3.1.x/quickstart/) etc.)
- Then, we need to connect the `app` i.e., initialized app /*object/* to the database
```Python
...
db.init_app(app)
...
```
- Creating the `model signature` of the `table signature`. You can understand your database as the table in which you can store your data in the rows. `Table signature` refer to
the "first row".
```Python
...
class Blog(db.Model):
    id: Mapped[int] = mapped_column(primary_key=True)
    title: Mapped[str]
    content: Mapped[str]
...
``` 

- Setting up the `routes` to serve the request from the client side. Let's discuss one route & the rest routes are the same as this.
```Python
...
@app.route("/")   <-- python decorator
def index():      <-- function signature
    return render_template("index.html")    
...
```
It renders the "index.html" template, providing the main content for the homepage of the web application. We can also add the `SQLalchemy` code in the function to make it connect to the databases.

Here, is the full code:

```Python
from flask import Flask, render_template, request
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy import Integer, String
from sqlalchemy.orm import Mapped, mapped_column

class Base(DeclarativeBase):
  pass

db = SQLAlchemy(model_class=Base)

app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///project.db"
db.init_app(app)

class Blog(db.Model):
    id: Mapped[int] = mapped_column(primary_key=True)
    title: Mapped[str]
    content: Mapped[str]


@app.route("/", methods=["GET"])
def index():
    print(Blog.query.all())
    return render_template("index.html", blogs = Blog.query.all())


@app.route("/", methods=["POST"])
def submit():
    title = request.form.get('title')
    content = request.form.get('content')
    blog = Blog(title=title, content=content)
    db.session.add(blog)
    db.session.commit()

    return render_template("index.html", blogs = Blog.query.all())

if __name__ == "__main__":
    with app.app_context():
        db.create_all()
    app.run(debug=True)

```

### Installing the libraries
We need to install `Flask` & `SQL_alchemy`.
```bash
pip install Flask
pip install SQLAlchemy
```

### Iterating blogs in the HTML with help of `jinja syntax` 

Jinja is a template engine for `Python`. You can read more about the jinja [here](https://jinja.palletsprojects.com/en/3.1.x/)

With the help of jinga syntax we can do iteration on the client side. We need to add these lines of code /*before/* the last closing `<div/>` tag. 

```html
{% for blog in blogs %}
        <div class="card mt-5">
            <div class="card-body">
                <h5 class="card-title">{{ blog.title }}</h5>
                <p class="card-text">{{ blog.content }}</p>
            </div>
        </div>
{% endfor %}
```

### Running the app
Open the `integrated terminal` of the code editor & run this command `python app.py` to run the project. Now you can go to your web browser and go to `http://127.0.0.1:5000/`

### tada ;) 😄😄😄
Your web application is running. :) 

I have also created a GitHub [repository](https://github.com/ankur0904/blog-flask-todo) for your reference.

###Technology Used
- python3
- Flask - A Python web framework
- SQL as a database
- SQLAlchemy - an Object-Relational Mapping (ORM) library for Python.

Hire me: ankursingh91002@gmail.com

[LinkedIn](https://www.linkedin.com/in/ankur-singh-161458227/)
[Twitter](https://twitter.com/ankursingh91002)