Flask Projects With Source Code

Coaching Management System Project In Flask


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

1. Database Structure

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

Tables

  • Users: Stores user information (coaches, students, and admins).
  • Coaches: Stores coach information.
  • Students: Stores student information.
  • Courses: Stores course details.
  • Sessions: Stores session 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='student')  # Roles: student, coach, admin
    coach = db.relationship('Coach', backref='user', uselist=False)
    student = db.relationship('Student', backref='user', uselist=False)
class Coach(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='coach', lazy=True)
    sessions = db.relationship('Session', backref='coach', lazy=True)
class Student(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)
    courses = db.relationship('Course', secondary='enrollment', backref='students', lazy=True)
    sessions = db.relationship('Session', secondary='attendance', backref='students', 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)
    coach_id = db.Column(db.Integer, db.ForeignKey('coach.id'), nullable=False)
    sessions = db.relationship('Session', 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)
    coach_id = db.Column(db.Integer, db.ForeignKey('coach.id'), nullable=False)
    session_date = db.Column(db.DateTime, nullable=False)
    duration = db.Column(db.Integer, nullable=False)  # in minutes
class Enrollment(db.Model):
    student_id = db.Column(db.Integer, db.ForeignKey('student.id'), primary_key=True)
    course_id = db.Column(db.Integer, db.ForeignKey('course.id'), primary_key=True)
class Attendance(db.Model):
    student_id = db.Column(db.Integer, db.ForeignKey('student.id'), primary_key=True)
    session_id = db.Column(db.Integer, db.ForeignKey('session.id'), primary_key=True)
    attended = db.Column(db.Boolean, default=False)
class Payment(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    student_id = db.Column(db.Integer, db.ForeignKey('student.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)

2. Flask Application Structure

Here’s the directory structure for the project:


coaching_management_system/
│
├── app.py
├── models.py
├── forms.py
├── templates/
│   ├── base.html
│   ├── index.html
│   ├── login.html
│   ├── register.html
│   ├── coach_dashboard.html
│   ├── student_dashboard.html
│   ├── admin_dashboard.html
│   ├── create_course.html
│   ├── create_session.html
│   ├── enroll_course.html
│   ├── view_courses.html
│   ├── view_sessions.html
│   ├── view_payments.html
│   └── manage_students.html
├── static/
│   ├── css/
│   │   └── styles.css
│   ├── js/
│   │   └── scripts.js
│   └── images/
└── requirements.txt

3. Flask Application Code

app.py


from flask import Flask, render_template, request, redirect, url_for, flash, session
from flask_sqlalchemy import SQLAlchemy
from models import db, User, Coach, Student, Course, Session, Payment
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:///coaching_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('coach_dashboard') if user.role == 'coach' else 'student_dashboard' if user.role == 'student' else 'admin_dashboard')
        flash('Login failed. Check your email and password.', 'danger')
    return render_template('login.html', form=form)
@app.route('/coach_dashboard')
def coach_dashboard():
    if 'user_id' not in session or session['role'] != 'coach':
        return redirect(url_for('login'))
    coach = Coach.query.filter_by(user_id=session['user_id']).first()
    return render_template('coach_dashboard.html', coach=coach)
@app.route('/student_dashboard')
def student_dashboard():
    if 'user_id' not in session or session['role'] != 'student':
        return redirect(url_for('login'))
    student = Student.query.filter_by(user_id=session['user_id']).first()
    return render_template('student_dashboard.html', student=student)
@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'] != 'coach':
        return redirect(url_for('login'))
    form = CourseForm()
    if form.validate_on_submit():
        course = Course(name=form.name.data, description=form.description.data, coach_id=session['user_id'])
        db.session.add(course)
        db.session.commit()
        flash('Course created successfully!', 'success')
        return redirect(url_for('coach_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'] != 'coach':
        return redirect(url_for('login'))
    form = SessionForm()
    if form.validate_on_submit():
        session_obj = Session(course_id=form.course_id.data, coach_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('coach_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'] != 'student':
        return redirect(url_for('login'))
    form = EnrollmentForm()
    if form.validate_on_submit():
        enrollment = Enrollment(student_id=session['user_id'], course_id=form.course_id.data)
        db.session.add(enrollment)
        db.session.commit()
        flash('Enrolled in course successfully!', 'success')
        return redirect(url_for('student_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'] != 'student':
        return redirect(url_for('login'))
    payments = Payment.query.filter_by(student_id=session['user_id']).all()
    return render_template('view_payments.html', payments=payments)
@app.route('/manage_students')
def manage_students():
    if 'user_id' not in session or session['role'] != 'admin':
        return redirect(url_for('login'))
    students = Student.query.all()
    return render_template('manage_students.html', students=students)
if __name__ == '__main__':
    with app.app_context():
        db.create_all()
    app.run(debug=True)

5. HTML Templates

1. 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`>
    <title>{% block title %}Coaching 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') }}`>Coaching 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'] == 'coach' %}
                            <li class=`nav-item`>
                                <a class=`nav-link` href=`{{ url_for('coach_dashboard') }}`>Dashboard</a>
                            </li>
                        {% elif session['role'] == 'student' %}
                            <li class=`nav-item`>
                                <a class=`nav-link` href=`{{ url_for('student_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>

2. templates/index.html


{% extends 'base.html' %}
{% block content %}
<h1>Welcome to the Coaching Management System</h1>
<p>Enhance your skills with our coaching 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 %}

3. 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 %}

4. 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 %}

5. templates/coach_dashboard.html


{% extends 'base.html' %}
{% block content %}
<h2>Coach Dashboard</h2>
<p>Welcome, {{ coach.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 %}

6. templates/student_dashboard.html


{% extends 'base.html' %}
{% block content %}
<h2>Student Dashboard</h2>
<p>Welcome, {{ student.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 %}

7. templates/admin_dashboard.html


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

8. 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 %}

9. 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 %}

10. 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 %}

11. 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>Coach</th>
        </tr>
    </thead>
    <tbody>
        {% for course in courses %}
        <tr>
            <td>{{ course.name }}</td>
            <td>{{ course.description }}</td>
            <td>{{ course.coach.name }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>
{% endblock %}

12. 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>Coach</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.coach.name }}</td>
            <td>{{ session.duration }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>
{% endblock %}

13. 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 %}

14. templates/manage_students.html


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

6. Static Files

1. static/css/styles.css


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

2. static/js/scripts.js


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

7. Requirements


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

Conclusion

This structure provides a comprehensive foundation for an advanced Coaching 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.