Flask Projects With Source Code

Training Management System Project In Flask


Creating an advanced-level Training Management System (TMS) with Flask and Bootstrap 5 involves designing a robust database structure, implementing backend logic, and creating responsive frontend pages. Below is a detailed implementation:

Database Structure

The database will be designed using SQLAlchemy (ORM for Flask). Here's the schema:

Tables

  • Users: Stores user information (trainers, trainees, and admins).
  • Trainers: Stores trainer information.
  • Trainees: Stores trainee information.
  • Courses: Stores course details.
  • Sessions: Stores session details.
  • Enrollments: Stores enrollment details.
  • Payments: Stores payment details.

Database Models


from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
db = SQLAlchemy()
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(50), unique=True, nullable=False)
    email = db.Column(db.String(100), unique=True, nullable=False)
    password = db.Column(db.String(200), nullable=False)
    role = db.Column(db.String(20), default='trainee')  # Roles: trainee, trainer, admin
    trainer = db.relationship('Trainer', backref='user', uselist=False)
    trainee = db.relationship('Trainee', backref='user', uselist=False)
class Trainer(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    name = db.Column(db.String(100), nullable=False)
    specialization = db.Column(db.String(100), nullable=False)
    courses = db.relationship('Course', backref='trainer', lazy=True)
    sessions = db.relationship('Session', backref='trainer', lazy=True)
class Trainee(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    name = db.Column(db.String(100), nullable=False)
    dob = db.Column(db.Date, nullable=False)
    gender = db.Column(db.String(10), nullable=False)
    phone = db.Column(db.String(15), nullable=False)
    enrollments = db.relationship('Enrollment', backref='trainee', lazy=True)
    payments = db.relationship('Payment', backref='trainee', lazy=True)
class Course(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    description = db.Column(db.Text, nullable=False)
    trainer_id = db.Column(db.Integer, db.ForeignKey('trainer.id'), nullable=False)
    sessions = db.relationship('Session', backref='course', lazy=True)
    enrollments = db.relationship('Enrollment', backref='course', lazy=True)
class Session(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    course_id = db.Column(db.Integer, db.ForeignKey('course.id'), nullable=False)
    trainer_id = db.Column(db.Integer, db.ForeignKey('trainer.id'), nullable=False)
    session_date = db.Column(db.DateTime, nullable=False)
    duration = db.Column(db.Integer, nullable=False)  # in minutes
class Enrollment(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    trainee_id = db.Column(db.Integer, db.ForeignKey('trainee.id'), nullable=False)
    course_id = db.Column(db.Integer, db.ForeignKey('course.id'), nullable=False)
    enrollment_date = db.Column(db.DateTime, nullable=False)
class Payment(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    trainee_id = db.Column(db.Integer, db.ForeignKey('trainee.id'), nullable=False)
    course_id = db.Column(db.Integer, db.ForeignKey('course.id'), nullable=False)
    payment_date = db.Column(db.DateTime, nullable=False)
    amount = db.Column(db.Float, nullable=False)

Flask Application Structure

Here’s the directory structure for the project:


training_management_system/
│
├── app.py
├── models.py
├── forms.py
├── templates/
│   ├── base.html
│   ├── index.html
│   ├── login.html
│   ├── register.html
│   ├── trainer_dashboard.html
│   ├── trainee_dashboard.html
│   ├── admin_dashboard.html
│   ├── create_course.html
│   ├── create_session.html
│   ├── enroll_course.html
│   ├── view_courses.html
│   ├── view_sessions.html
│   ├── view_payments.html
│   └── manage_trainees.html
├── static/
│   ├── css/
│   │   └── styles.css
│   ├── js/
│   │   └── scripts.js
│   └── images/
└── requirements.txt

Flask Application Code


from flask import Flask, render_template, request, redirect, url_for, flash, session
from flask_sqlalchemy import SQLAlchemy
from models import db, User, Trainer, Trainee, Course, Session, Payment, Enrollment
from forms import LoginForm, RegistrationForm, CourseForm, SessionForm, EnrollmentForm
from datetime import datetime
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///training_management.db'
db.init_app(app)
# Routes
@app.route('/')
def index():
    return render_template('index.html')
@app.route('/register', methods=['GET', 'POST'])
def register():
    form = RegistrationForm()
    if form.validate_on_submit():
        user = User(username=form.username.data, email=form.email.data, password=form.password.data)
        db.session.add(user)
        db.session.commit()
        flash('Registration successful! Please login.', 'success')
        return redirect(url_for('login'))
    return render_template('register.html', form=form)
@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(email=form.email.data).first()
        if user and user.password == form.password.data:  # Use hashed passwords in production
            session['user_id'] = user.id
            session['role'] = user.role
            flash('Login successful!', 'success')
            return redirect(url_for('trainer_dashboard') if user.role == 'trainer' else 'trainee_dashboard' if user.role == 'trainee' else 'admin_dashboard')
        flash('Login failed. Check your email and password.', 'danger')
    return render_template('login.html', form=form)
@app.route('/trainer_dashboard')
def trainer_dashboard():
    if 'user_id' not in session or session['role'] != 'trainer':
        return redirect(url_for('login'))
    trainer = Trainer.query.filter_by(user_id=session['user_id']).first()
    return render_template('trainer_dashboard.html', trainer=trainer)
@app.route('/trainee_dashboard')
def trainee_dashboard():
    if 'user_id' not in session or session['role'] != 'trainee':
        return redirect(url_for('login'))
    trainee = Trainee.query.filter_by(user_id=session['user_id']).first()
    return render_template('trainee_dashboard.html', trainee=trainee)
@app.route('/admin_dashboard')
def admin_dashboard():
    if 'user_id' not in session or session['role'] != 'admin':
        return redirect(url_for('login'))
    return render_template('admin_dashboard.html')
@app.route('/create_course', methods=['GET', 'POST'])
def create_course():
    if 'user_id' not in session or session['role'] != 'trainer':
        return redirect(url_for('login'))
    form = CourseForm()
    if form.validate_on_submit():
        course = Course(name=form.name.data, description=form.description.data, trainer_id=session['user_id'])
        db.session.add(course)
        db.session.commit()
        flash('Course created successfully!', 'success')
        return redirect(url_for('trainer_dashboard'))
    return render_template('create_course.html', form=form)
@app.route('/create_session', methods=['GET', 'POST'])
def create_session():
    if 'user_id' not in session or session['role'] != 'trainer':
        return redirect(url_for('login'))
    form = SessionForm()
    if form.validate_on_submit():
        session_obj = Session(course_id=form.course_id.data, trainer_id=session['user_id'], session_date=form.session_date.data, duration=form.duration.data)
        db.session.add(session_obj)
        db.session.commit()
        flash('Session created successfully!', 'success')
        return redirect(url_for('trainer_dashboard'))
    return render_template('create_session.html', form=form)
@app.route('/enroll_course', methods=['GET', 'POST'])
def enroll_course():
    if 'user_id' not in session or session['role'] != 'trainee':
        return redirect(url_for('login'))
    form = EnrollmentForm()
    if form.validate_on_submit():
        enrollment = Enrollment(trainee_id=session['user_id'], course_id=form.course_id.data, enrollment_date=datetime.now())
        db.session.add(enrollment)
        db.session.commit()
        flash('Enrolled in course successfully!', 'success')
        return redirect(url_for('trainee_dashboard'))
    return render_template('enroll_course.html', form=form)
@app.route('/view_courses')
def view_courses():
    if 'user_id' not in session:
        return redirect(url_for('login'))
    courses = Course.query.all()
    return render_template('view_courses.html', courses=courses)
@app.route('/view_sessions')
def view_sessions():
    if 'user_id' not in session:
        return redirect(url_for('login'))
    sessions = Session.query.all()
    return render_template('view_sessions.html', sessions=sessions)
@app.route('/view_payments')
def view_payments():
    if 'user_id' not in session or session['role'] != 'trainee':
        return redirect(url_for('login'))
    payments = Payment.query.filter_by(trainee_id=session['user_id']).all()
    return render_template('view_payments.html', payments=payments)
@app.route('/manage_trainees')
def manage_trainees():
    if 'user_id' not in session or session['role'] != 'admin':
        return redirect(url_for('login'))
    trainees = Trainee.query.all()
    return render_template('manage_trainees.html', trainees=trainees)
if __name__ == '__main__':
    with app.app_context():
        db.create_all()
    app.run(debug=True)

models.py


from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
db = SQLAlchemy()
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(50), unique=True, nullable=False)
    email = db.Column(db.String(100), unique=True, nullable=False)
    password = db.Column(db.String(200), nullable=False)
    role = db.Column(db.String(20), default='trainee')  # Roles: trainee, trainer, admin
    trainer = db.relationship('Trainer', backref='user', uselist=False)
    trainee = db.relationship('Trainee', backref='user', uselist=False)
class Trainer(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    name = db.Column(db.String(100), nullable=False)
    specialization = db.Column(db.String(100), nullable=False)
    courses = db.relationship('Course', backref='trainer', lazy=True)
    sessions = db.relationship('Session', backref='trainer', lazy=True)
class Trainee(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    name = db.Column(db.String(100), nullable=False)
    dob = db.Column(db.Date, nullable=False)
    gender = db.Column(db.String(10), nullable=False)
    phone = db.Column(db.String(15), nullable=False)
    enrollments = db.relationship('Enrollment', backref='trainee', lazy=True)
    payments = db.relationship('Payment', backref='trainee', lazy=True)
class Course(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(100), nullable=False)
    description = db.Column(db.Text, nullable=False)
    trainer_id = db.Column(db.Integer, db.ForeignKey('trainer.id'), nullable=False)
    sessions = db.relationship('Session', backref='course', lazy=True)
    enrollments = db.relationship('Enrollment', backref='course', lazy=True)
class Session(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    course_id = db.Column(db.Integer, db.ForeignKey('course.id'), nullable=False)
    trainer_id = db.Column(db.Integer, db.ForeignKey('trainer.id'), nullable=False)
    session_date = db.Column(db.DateTime, nullable=False)
    duration = db.Column(db.Integer, nullable=False)  # in minutes
class Enrollment(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    trainee_id = db.Column(db.Integer, db.ForeignKey('trainee.id'), nullable=False)
    course_id = db.Column(db.Integer, db.ForeignKey('course.id'), nullable=False)
    enrollment_date = db.Column(db.DateTime, nullable=False)
class Payment(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    trainee_id = db.Column(db.Integer, db.ForeignKey('trainee.id'), nullable=False)
    course_id = db.Column(db.Integer, db.ForeignKey('course.id'), nullable=False)
    payment_date = db.Column(db.DateTime, nullable=False)
    amount = db.Column(db.Float, nullable=False)

forms.py


from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, DateField, SelectField, IntegerField, TextAreaField, SubmitField, DecimalField
from wtforms.validators import DataRequired, Email, Length
class RegistrationForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired(), Length(min=2, max=50)])
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired(), Length(min=6, max=200)])
    submit = SubmitField('Register')
class LoginForm(FlaskForm):
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    submit = SubmitField('Login')
class CourseForm(FlaskForm):
    name = StringField('Course Name', validators=[DataRequired()])
    description = TextAreaField('Description', validators=[DataRequired()])
    submit = SubmitField('Create Course')
class SessionForm(FlaskForm):
    course_id = SelectField('Course', coerce=int, validators=[DataRequired()])
    session_date = DateField('Session Date', format='%Y-%m-%d', validators=[DataRequired()])
    duration = IntegerField('Duration (in minutes)', validators=[DataRequired()])
    submit = SubmitField('Create Session')
class EnrollmentForm(FlaskForm):
    course_id = SelectField('Course', coerce=int, validators=[DataRequired()])
    submit = SubmitField('Enroll in Course')
class PaymentForm(FlaskForm):
    amount = DecimalField('Amount', validators=[DataRequired()])
    submit = SubmitField('Make Payment')

HTML Templates

templates/base.html


<!DOCTYPE html>
<html lang=`en`>
<head>
    <meta charset=`UTF-8`>
    <meta name=`viewport` content=`width=device-width, initial-scale=1.0`>
    <link href=`https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css` rel=`stylesheet`>
    <link rel=`stylesheet` href=`{{ url_for('static', filename='css/styles.css') }}`>
    <title>{% block title %}Training Management System{% endblock %}</title>
</head>
<body>
    <nav class=`navbar navbar-expand-lg navbar-light bg-light`>
        <div class=`container-fluid`>
            <a class=`navbar-brand` href=`{{ url_for('index') }}`>Training Management</a>
            <button class=`navbar-toggler` type=`button` data-bs-toggle=`collapse` data-bs-target=`#navbarNav` aria-controls=`navbarNav` aria-expanded=`false` aria-label=`Toggle navigation`>
                <span class=`navbar-toggler-icon`></span>
            </button>
            <div class=`collapse navbar-collapse` id=`navbarNav`>
                <ul class=`navbar-nav`>
                    {% if 'user_id' in session %}
                        {% if session['role'] == 'trainer' %}
                            <li class=`nav-item`>
                                <a class=`nav-link` href=`{{ url_for('trainer_dashboard') }}`>Dashboard</a>
                            </li>
                        {% elif session['role'] == 'trainee' %}
                            <li class=`nav-item`>
                                <a class=`nav-link` href=`{{ url_for('trainee_dashboard') }}`>Dashboard</a>
                            </li>
                        {% elif session['role'] == 'admin' %}
                            <li class=`nav-item`>
                                <a class=`nav-link` href=`{{ url_for('admin_dashboard') }}`>Dashboard</a>
                            </li>
                        {% endif %}
                        <li class=`nav-item`>
                            <a class=`nav-link` href=`{{ url_for('logout') }}`>Logout</a>
                        </li>
                    {% else %}
                        <li class=`nav-item`>
                            <a class=`nav-link` href=`{{ url_for('login') }}`>Login</a>
                        </li>
                        <li class=`nav-item`>
                            <a class=`nav-link` href=`{{ url_for('register') }}`>Register</a>
                        </li>
                    {% endif %}
                </ul>
            </div>
        </div>
    </nav>
    <div class=`container mt-4`>
        {% with messages = get_flashed_messages() %}
            {% if messages %}
                <div class=`alert alert-info`>
                    {% for message in messages %}
                        {{ message }}<br>
                    {% endfor %}
                </div>
            {% endif %}
        {% endwith %}
        {% block content %}{% endblock %}
    </div>
    <script src=`https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js`></script>
</body>
</html>

templates/index.html


{% extends 'base.html' %}
{% block content %}
<h1>Welcome to the Training Management System</h1>
<p>Enhance your skills with our training programs!</p>
<a href=`{{ url_for('register') }}` class=`btn btn-primary`>Register</a>
<a href=`{{ url_for('login') }}` class=`btn btn-secondary`>Login</a>
{% endblock %}

templates/login.html


{% extends 'base.html' %}
{% block content %}
<h2>Login</h2>
<form method=`POST`>
    {{ form.hidden_tag() }}
    <div class=`mb-3`>
        {{ form.email.label(class=`form-label`) }}
        {{ form.email(class=`form-control`) }}
    </div>
    <div class=`mb-3`>
        {{ form.password.label(class=`form-label`) }}
        {{ form.password(class=`form-control`) }}
    </div>
    {{ form.submit(class=`btn btn-primary`) }}
</form>
{% endblock %}

templates/register.html


{% extends 'base.html' %}
{% block content %}
<h2>Register</h2>
<form method=`POST`>
    {{ form.hidden_tag() }}
    <div class=`mb-3`>
        {{ form.username.label(class=`form-label`) }}
        {{ form.username(class=`form-control`) }}
    </div>
    <div class=`mb-3`>
        {{ form.email.label(class=`form-label`) }}
        {{ form.email(class=`form-control`) }}
    </div>
    <div class=`mb-3`>
        {{ form.password.label(class=`form-label`) }}
        {{ form.password(class=`form-control`) }}
    </div>
    {{ form.submit(class=`btn btn-primary`) }}
</form>
{% endblock %}

templates/trainer_dashboard.html


{% extends 'base.html' %}
{% block content %}
<h2>Trainer Dashboard</h2>
<p>Welcome, {{ trainer.name }}!</p>
<a href=`{{ url_for('create_course') }}` class=`btn btn-primary`>Create Course</a>
<a href=`{{ url_for('create_session') }}` class=`btn btn-secondary`>Create Session</a>
<a href=`{{ url_for('view_sessions') }}` class=`btn btn-info`>View Sessions</a>
{% endblock %}

templates/trainee_dashboard.html


{% extends 'base.html' %}
{% block content %}
<h2>Trainee Dashboard</h2>
<p>Welcome, {{ trainee.name }}!</p>
<a href=`{{ url_for('enroll_course') }}` class=`btn btn-primary`>Enroll in Course</a>
<a href=`{{ url_for('view_courses') }}` class=`btn btn-secondary`>View Courses</a>
<a href=`{{ url_for('view_payments') }}` class=`btn btn-info`>View Payments</a>
{% endblock %}

templates/admin_dashboard.html


{% extends 'base.html' %}
{% block content %}
<h2>Admin Dashboard</h2>
<p>Welcome, Admin!</p>
<a href=`{{ url_for('manage_trainees') }}` class=`btn btn-primary`>Manage Trainees</a>
{% endblock %}

templates/create_course.html


{% extends 'base.html' %}
{% block content %}
<h2>Create Course</h2>
<form method=`POST`>
    {{ form.hidden_tag() }}
    <div class=`mb-3`>
        {{ form.name.label(class=`form-label`) }}
        {{ form.name(class=`form -control`) }}
    </div>
    <div class=`mb-3`>
        {{ form.description.label(class=`form-label`) }}
        {{ form.description(class=`form-control`) }}
    </div>
    {{ form.submit(class=`btn btn-primary`) }}
</form>
{% endblock %}

templates/create_session.html


{% extends 'base.html' %}
{% block content %}
<h2>Create Session</h2>
<form method=`POST`>
    {{ form.hidden_tag() }}
    <div class=`mb-3`>
        {{ form.course_id.label(class=`form-label`) }}
        {{ form.course_id(class=`form-control`) }}
    </div>
    <div class=`mb-3`>
        {{ form.session_date.label(class=`form-label`) }}
        {{ form.session_date(class=`form-control`) }}
    </div>
    <div class=`mb-3`>
        {{ form.duration.label(class=`form-label`) }}
        {{ form.duration(class=`form-control`) }}
    </div>
    {{ form.submit(class=`btn btn-primary`) }}
</form>
{% endblock %}

templates/enroll_course.html


{% extends 'base.html' %}
{% block content %}
<h2>Enroll in Course</h2>
<form method=`POST`>
    {{ form.hidden_tag() }}
    <div class=`mb-3`>
        {{ form.course_id.label(class=`form-label`) }}
        {{ form.course_id(class=`form-control`) }}
    </div>
    {{ form.submit(class=`btn btn-primary`) }}
</form>
{% endblock %}

templates/view_courses.html


{% extends 'base.html' %}
{% block content %}
<h2>Available Courses</h2>
<table class=`table`>
    <thead>
        <tr>
            <th>Course Name</th>
            <th>Description</th>
            <th>Trainer</th>
        </tr>
    </thead>
    <tbody>
        {% for course in courses %}
        <tr>
            <td>{{ course.name }}</td>
            <td>{{ course.description }}</td>
            <td>{{ course.trainer.name }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>
{% endblock %}

templates/view_sessions.html


{% extends 'base.html' %}
{% block content %}
<h2>Upcoming Sessions</h2>
<table class=`table`>
    <thead>
        <tr>
            <th>Session Date</th>
            <th>Course</th>
            <th>Trainer</th>
            <th>Duration (minutes)</th>
        </tr>
    </thead>
    <tbody>
        {% for session in sessions %}
        <tr>
            <td>{{ session.session_date }}</td>
            <td>{{ session.course.name }}</td>
            <td>{{ session.trainer.name }}</td>
            <td>{{ session.duration }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>
{% endblock %}

templates/view_payments.html


{% extends 'base.html' %}
{% block content %}
<h2>Your Payments</h2>
<table class=`table`>
    <thead>
        <tr>
            <th>Payment Date</th>
            <th>Course</th>
            <th>Amount</th>
        </tr>
    </thead>
    <tbody>
        {% for payment in payments %}
        <tr>
            <td>{{ payment.payment_date }}</td>
            <td>{{ payment.course.name }}</td>
            <td>{{ payment.amount }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>
{% endblock %}

templates/manage_trainees.html


{% extends 'base.html' %}
{% block content %}
<h2>Manage Trainees</h2>
<table class=`table`>
    <thead>
        <tr>
            <th>Name</th>
            <th>Email</th>
            <th>Phone</th>
        </tr>
    </thead>
    <tbody>
        {% for trainee in trainees %}
        <tr>
            <td>{{ trainee.name }}</td>
            <td>{{ trainee.user.email }}</td>
            <td>{{ trainee.phone }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>
{% endblock %}

Static Files

static/css/styles.css


body {
    background-color: #f8f9fa;
}
.navbar {
    margin-bottom: 20px;
}
.table {
    margin-top: 20px;
}

JavaScript

static/js/scripts.js


// Custom JavaScript can be added here
document.addEventListener('DOMContentLoaded', function() {
    console.log(`Training Management System Loaded`);
});

Requirements

requirements.txt


Flask==2.0.1
Flask-SQLAlchemy==2.5.1
Flask-WTF==0.15.1
WTForms==2.3.3

This structure provides a comprehensive foundation for an advanced Training Management System using Flask and Bootstrap 5. You can expand upon this by adding features such as notifications, advanced reporting, and user management functionalities.

Written by Surfside Media

Senior Full Stack Developer specializing in Web Technologies.