This article gives access to the source code of a basic template for a Python app containing a CRUD. The code uses Flask and SQLAlchemy.
In order to start any new project containing a CRUD in a quick way, you can use this code or clone it from Github (link below) as a starter for your project and then modify and complete it with your own code.
Useful links:
- GitHub repository
- Flask-SQLAlchemy Documentation
- How to Build a CRUD App with Flask and SQLAlchemy in Python
- Flask SQLAlchemy (with Examples)
Code of the app
# app.py
from flask import Flask, render_template, redirect, flash, url_for, request
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# Config & Connexion to database
app.secret_key = "any_random_string"
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# Model definition (= tables creation)
class User(db.Model):
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(255))
email = db.Column(db.String(255))
def __init__(self, name, email):
self.name = name
self.email = email
@app.route('/')
def index():
users = User.query.all()
return render_template("index.html", users=users)
@app.route('/add', methods=['GET', 'POST'])
def add():
if request.method == 'POST':
# Get data from the form
name = request.form.get('name')
email = request.form.get('email')
# Save to db
user = User(name, email)
db.session.add(user)
db.session.commit()
# Redirect
flash("User added.")
return redirect(url_for('index'))
else:
return render_template('add.html')
@app.route('/edit', methods=['GET', 'POST'])
def edit():
if request.method == 'POST':
user = User.query.get(request.form.get('id'))
user.name = request.form.get('name')
user.email = request.form.get('email')
db.session.commit()
flash("User edited.")
else:
id=request.args.get('id')
if not id:
flash("No user ID provided.")
else:
user=User.query.get(id)
return render_template('edit.html', user=user)
return redirect(url_for('index'))
@app.route('/delete')
def delete():
id=request.args.get('id')
if not id:
flash("No user ID provided.")
else:
db.session.delete(User.query.get(id))
db.session.commit()
flash("User deleted.")
return redirect(url_for('index'))
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.1/css/bootstrap.min.css" integrity="sha512-siwe/oXMhSjGCwLn+scraPOWrJxHlUgMBMZXdPe2Tnk3I0x3ESCoLz7WZ5NTH6SZrywMY+PB1cjyqJ5jAluCOg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<div class="container py-3">
<h1>{{ self.title() }}</h1>
<!-- Alerts -->
{% if get_flashed_messages() %}
<div class="alert alert-primary alert-dismissable">
{% for message in get_flashed_messages() %}
<div>{{ message }}</div>
{% endfor %}
</div>
{% endif %}
<!-- Content -->
{% block content %}{% endblock %}
</div>
</body>
</html>
<!-- templates/index.html -->
{% extends 'base.html' %}
{% block title %}Home{% endblock %}
{% block content %}
<h2>Users <a href="{{ url_for('add') }}" class="btn btn-success">Add new</a></h2>
<table class="table table-hover">
<tr>
<th>ID</th>
<th>Name</th>
<th>Email</th>
<th>Actions</th>
</tr>
{% for user in users %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.email }}</td>
<td>
<a href="{{ url_for('edit', id=user.id) }}" class="btn btn-primary btn-xs">Edit</a>
<a href="{{ url_for('delete', id=user.id) }}" class="btn btn-danger btn-xs" onclick="return confirm('Are you sure to delete?')">Delete</a>
</td>
</tr>
{% endfor %}
</table>
{% endblock %}
<!-- templates/add.html -->
{% extends 'base.html' %}
{% block title %}Add a user{% endblock %}
{% block content %}
<form action="{{ url_for('add') }}" method="POST">
<div class="form-group">
<label>Name:</label>
<input type="text" class="form-control" name="name" required>
</div>
<div class="form-group">
<label>Email:</label>
<input type="email" class="form-control" name="email" required>
</div>
<div class="form-group">
<button class="btn btn-primary" type="submit">Add user</button>
</div>
<div>
</form>
{% endblock %}
<!-- templates/edit.html -->
{% extends 'base.html' %}
{% block title %}Add a user{% endblock %}
{% block content %}
<form action="{{ url_for('edit') }}" method="POST">
<div class="form-group">
<label>Name:</label>
<input type="hidden" name="id" value="{{user.id}}">
<input type="text" class="form-control" name="name" value="{{user.name}}">
</div>
<div class="form-group">
<label>Email:</label>
<input type="email" class="form-control" name="email" value="{{user.email}}">
</div>
<div class="form-group">
<button class="btn btn-primary" type="submit">Update</button>
</div>
<div>
</form>
{% endblock %}
Create the database
- Create an empty file called
app.db
- In the terminal, browse to the current app.py location and type the following list of commands.
# Terminal
$ python3
$ >>> from app import db
$ >>> db.create_all()
If we check now the database, a table “User” have been created.
It was useful, it made a good basis to start working. Should be better to use constraits on fields though