Building a Simple CRUD Web App in Python (with Flask + SQLite)

One of the best ways to get job-ready with Python is by building small, functional apps. In this guide, we’ll create a Notes App where you can:

  • Create new notes
  • Read all saved notes
  • Update existing notes
  • Delete notes

And unlike an in-memory app, this one will use SQLite so your notes are stored in a database and won’t disappear when you restart the server.


1. Why Flask + SQLite?

  • Flask → A lightweight Python web framework. Perfect for learning and small apps.
  • SQLite → A file-based database that comes built into Python (sqlite3). No extra installation needed.

This combo is ideal when you’re just starting with web development.


2. Project Setup

Create a folder structure like this:

crud_app/

├── app.py        # main Flask app
├── templates/
   ├── base.html
   ├── index.html
   ├── edit.html

👉 Flask automatically looks inside templates/ for HTML files.

3. Installing Flask

Run this in your terminal:

pip install flask

4. The Flask App (app.py)

import sqlite3
from flask import Flask, render_template, request, redirect

app = Flask(__name__)

# Connect to SQLite
def get_db_connection():
    conn = sqlite3.connect('notes.db')
    conn.row_factory = sqlite3.Row  # lets us access rows as dict-like objects
    return conn

# Initialize DB with a notes table
def init_db():
    conn = get_db_connection()
    conn.execute('''
        CREATE TABLE IF NOT EXISTS notes (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            content TEXT NOT NULL
        )
    ''')
    conn.commit()
    conn.close()

init_db()

# READ: Show all notes
@app.route('/')
def index():
    conn = get_db_connection()
    notes = conn.execute('SELECT * FROM notes').fetchall()
    conn.close()
    return render_template('index.html', notes=notes)

# CREATE: Add a new note
@app.route('/add', methods=['POST'])
def add_note():
    note = request.form.get('note')
    if note:
        conn = get_db_connection()
        conn.execute('INSERT INTO notes (content) VALUES (?)', (note,))
        conn.commit()
        conn.close()
    return redirect('/')

# UPDATE: Edit an existing note
@app.route('/edit/<int:id>', methods=['GET', 'POST'])
def edit(id):
    conn = get_db_connection()
    note = conn.execute('SELECT * FROM notes WHERE id = ?', (id,)).fetchone()

    if request.method == 'POST':
        new_content = request.form.get('note')
        conn.execute('UPDATE notes SET content = ? WHERE id = ?', (new_content, id))
        conn.commit()
        conn.close()
        return redirect('/')
    
    conn.close()
    return render_template('edit.html', note=note)

# DELETE: Remove a note
@app.route('/delete/<int:id>')
def delete(id):
    conn = get_db_connection()
    conn.execute('DELETE FROM notes WHERE id = ?', (id,))
    conn.commit()
    conn.close()
    return redirect('/')

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

What’s happening here:

  • get_db_connection() → opens a connection to notes.db.
  • init_db() → makes sure the notes table exists.
  • / (GET) → fetches all notes and shows them.
  • /add (POST) → adds a new note.
  • /edit/<id> → lets you edit a note.
  • /delete/<id> → removes a note.

5. Templates

templates/base.html

A base layout so you don’t repeat boilerplate.

<!doctype html>
<html>
<head>
    <title>Simple Notes App</title>
</head>
<body>
    <h1>My Notes</h1>
    {% block content %}{% endblock %}
</body>
</html>

templates/index.html

Shows the form and the list of notes.

{% extends 'base.html' %}
{% block content %}
<form method="post" action="/add">
    <input type="text" name="note" placeholder="Write a note">
    <button type="submit">Add</button>
</form>

<ul>
{% for note in notes %}
    <li>
        {{ note.content }}
        <a href="/edit/{{ note.id }}">Edit</a>
        <a href="/delete/{{ note.id }}">Delete</a>
    </li>
{% endfor %}
</ul>
{% endblock %}

templates/edit.html

Form for editing a note.

{% extends 'base.html' %}
{% block content %}
<form method="post">
    <input type="text" name="note" value="{{ note.content }}">
    <button type="submit">Update</button>
</form>
{% endblock %}

6. Running the App

Run:

python app.py

Visit http://127.0.0.1:5000 in your browser. Now your notes are saved in notes.db.

Leave a Reply