Final Year Projects Source Mega Final Year projects

College Management System Project in Python Source Code 2026

College Management System Project in Python Source Code - Feature image

If you’re a student hunting for a solid project — the kind that’s actually useful, looks good in a submission, and isn’t the same tired calculator everyone builds — a college management system project in Python is one of the best choices in 2026. It touches the core skills examiners look for: data handling, functions, file storage, and a clean menu system.

In this post you’ll get three full, working versions of a college management system in Python — a simple console version, a GUI version with Tkinter, and a database version with SQLite — plus a line-by-line explanation, ideas to extend it, project report tips, and the viva questions examiners actually ask. Everything uses Python’s built-in features, so there’s nothing extra to install.

What This Project Does

This is a console-based college management system that lets you manage students and their records. It’s deliberately clean and beginner-friendly, while still covering real concepts. Features included:

  • Add a new student with name, roll number, course, and marks
  • View all students in a neat list
  • Search for a student by roll number
  • Update a student’s details
  • Delete a student record
  • Data saved to a file, so records stay even after you close the program

Technologies Used

  • Python 3 — the only thing you need installed
  • JSON file storage — built into Python, no database setup required
  • Functions & dictionaries — clean, readable structure

College Management System in Python — Full Source Code

Copy the entire code below into a file called college_management.py and run it.

import json
import os

DATA_FILE = "students.json"


def load_students():
    if os.path.exists(DATA_FILE):
        with open(DATA_FILE, "r") as f:
            return json.load(f)
    return []


def save_students(students):
    with open(DATA_FILE, "w") as f:
        json.dump(students, f, indent=4)


def add_student(students):
    roll = input("Enter roll number: ").strip()
    for s in students:
        if s["roll"] == roll:
            print("A student with this roll number already exists.\n")
            return
    name = input("Enter name: ").strip()
    course = input("Enter course: ").strip()
    marks = input("Enter marks: ").strip()
    students.append({"roll": roll, "name": name,
                     "course": course, "marks": marks})
    save_students(students)
    print("Student added successfully!\n")


def view_students(students):
    if not students:
        print("No student records found.\n")
        return
    print("\n--- All Students ---")
    print(f"{'Roll':<10}{'Name':<20}{'Course':<15}{'Marks':<8}")
    print("-" * 53)
    for s in students:
        print(f"{s['roll']:<10}{s['name']:<20}{s['course']:<15}{s['marks']:<8}")
    print()


def search_student(students):
    roll = input("Enter roll number to search: ").strip()
    for s in students:
        if s["roll"] == roll:
            print(f"\nFound: {s['name']} | {s['course']} | Marks: {s['marks']}\n")
            return
    print("No student found with that roll number.\n")


def update_student(students):
    roll = input("Enter roll number to update: ").strip()
    for s in students:
        if s["roll"] == roll:
            s["name"] = input("New name: ").strip() or s["name"]
            s["course"] = input("New course: ").strip() or s["course"]
            s["marks"] = input("New marks: ").strip() or s["marks"]
            save_students(students)
            print("Record updated!\n")
            return
    print("No student found with that roll number.\n")


def delete_student(students):
    roll = input("Enter roll number to delete: ").strip()
    for s in students:
        if s["roll"] == roll:
            students.remove(s)
            save_students(students)
            print("Record deleted!\n")
            return
    print("No student found with that roll number.\n")


def menu():
    students = load_students()
    while True:
        print("===== College Management System =====")
        print("1. Add Student")
        print("2. View All Students")
        print("3. Search Student")
        print("4. Update Student")
        print("5. Delete Student")
        print("6. Exit")
        choice = input("Choose an option (1-6): ").strip()

        if choice == "1":
            add_student(students)
        elif choice == "2":
            view_students(students)
        elif choice == "3":
            search_student(students)
        elif choice == "4":
            update_student(students)
        elif choice == "5":
            delete_student(students)
        elif choice == "6":
            print("Goodbye!")
            break
        else:
            print("Invalid choice. Try again.\n")


if __name__ == "__main__":
    menu()

How to Run This Project

  • Make sure Python 3 is installed (type python --version to check).
  • Save the code in a file named college_management.py.
  • Open a terminal in that folder and run: python college_management.py
  • Use the menu to add, view, search, update, and delete students.
Note: A file called students.json is created automatically to store your data, so records are saved between runs.

How the Code Works (Quick Walkthrough)

The whole system is built around a list of dictionaries — each student is one dictionary with a roll number, name, course, and marks. The load_students() and save_students() functions read and write that list to a JSON file, which is how your data survives after closing the program. Each menu option calls a small, focused function, which keeps the code clean and easy to extend.

Version 2 — College Management System With Tkinter GUI

A console app is a good start, but a window with buttons instantly looks more impressive in a demo or submission. This version uses Tkinter — Python’s built-in GUI library — so there’s still nothing to install. Save it as college_gui.py and run it the same way.

import json
import os
import tkinter as tk
from tkinter import messagebox, simpledialog

DATA_FILE = "students.json"


def load_students():
    if os.path.exists(DATA_FILE):
        with open(DATA_FILE, "r") as f:
            return json.load(f)
    return []


def save_students(students):
    with open(DATA_FILE, "w") as f:
        json.dump(students, f, indent=4)


class CollegeApp:
    def __init__(self, root):
        self.root = root
        self.root.title("College Management System")
        self.root.geometry("560x420")
        self.students = load_students()

        title = tk.Label(root, text="College Management System",
                         font=("Segoe UI", 16, "bold"))
        title.pack(pady=10)

        self.listbox = tk.Listbox(root, width=70, height=12)
        self.listbox.pack(pady=8)

        btns = tk.Frame(root)
        btns.pack(pady=8)

        tk.Button(btns, text="Add", width=10,
                  command=self.add_student).grid(row=0, column=0, padx=5)
        tk.Button(btns, text="Search", width=10,
                  command=self.search_student).grid(row=0, column=1, padx=5)
        tk.Button(btns, text="Update", width=10,
                  command=self.update_student).grid(row=0, column=2, padx=5)
        tk.Button(btns, text="Delete", width=10,
                  command=self.delete_student).grid(row=0, column=3, padx=5)

        self.refresh_list()

    def refresh_list(self):
        self.listbox.delete(0, tk.END)
        for s in self.students:
            line = f"{s['roll']:<8} {s['name']:<20} {s['course']:<12} {s['marks']}"
            self.listbox.insert(tk.END, line)

    def add_student(self):
        roll = simpledialog.askstring("Add", "Roll number:")
        if not roll:
            return
        if any(s["roll"] == roll for s in self.students):
            messagebox.showerror("Error", "Roll number already exists.")
            return
        name = simpledialog.askstring("Add", "Name:") or ""
        course = simpledialog.askstring("Add", "Course:") or ""
        marks = simpledialog.askstring("Add", "Marks:") or ""
        self.students.append({"roll": roll, "name": name,
                              "course": course, "marks": marks})
        save_students(self.students)
        self.refresh_list()

    def search_student(self):
        roll = simpledialog.askstring("Search", "Roll number:")
        for s in self.students:
            if s["roll"] == roll:
                messagebox.showinfo(
                    "Found",
                    f"Name: {s['name']}\nCourse: {s['course']}\nMarks: {s['marks']}")
                return
        messagebox.showwarning("Not found", "No student with that roll number.")

    def update_student(self):
        roll = simpledialog.askstring("Update", "Roll number to update:")
        for s in self.students:
            if s["roll"] == roll:
                s["name"] = simpledialog.askstring(
                    "Update", "New name:", initialvalue=s["name"]) or s["name"]
                s["course"] = simpledialog.askstring(
                    "Update", "New course:", initialvalue=s["course"]) or s["course"]
                s["marks"] = simpledialog.askstring(
                    "Update", "New marks:", initialvalue=s["marks"]) or s["marks"]
                save_students(self.students)
                self.refresh_list()
                return
        messagebox.showwarning("Not found", "No student with that roll number.")

    def delete_student(self):
        roll = simpledialog.askstring("Delete", "Roll number to delete:")
        for s in self.students:
            if s["roll"] == roll:
                if messagebox.askyesno("Confirm", f"Delete {s['name']}?"):
                    self.students.remove(s)
                    save_students(self.students)
                    self.refresh_list()
                return
        messagebox.showwarning("Not found", "No student with that roll number.")


if __name__ == "__main__":
    root = tk.Tk()
    CollegeApp(root)
    root.mainloop()
Why examiners like this version: it shows you understand classes (OOP), event-driven programming, and GUI layout — three things that separate a good submission from a copy-paste one.

Version 3 — College Management System With SQLite Database

Want to show real database skills? This version swaps the JSON file for SQLite — a genuine SQL database that’s built into Python, so there’s still nothing to install. It’s the closest to how real systems work, and it lets you honestly write “database integration” in your project report.

import sqlite3

DB_FILE = "college.db"


def get_connection():
    conn = sqlite3.connect(DB_FILE)
    conn.execute("""CREATE TABLE IF NOT EXISTS students (
                        roll TEXT PRIMARY KEY,
                        name TEXT NOT NULL,
                        course TEXT,
                        marks TEXT)""")
    return conn


def add_student():
    roll = input("Enter roll number: ").strip()
    name = input("Enter name: ").strip()
    course = input("Enter course: ").strip()
    marks = input("Enter marks: ").strip()
    conn = get_connection()
    try:
        conn.execute("INSERT INTO students VALUES (?, ?, ?, ?)",
                     (roll, name, course, marks))
        conn.commit()
        print("Student added!\n")
    except sqlite3.IntegrityError:
        print("A student with this roll number already exists.\n")
    finally:
        conn.close()


def view_students():
    conn = get_connection()
    rows = conn.execute("SELECT * FROM students ORDER BY roll").fetchall()
    conn.close()
    if not rows:
        print("No records found.\n")
        return
    print(f"\n{'Roll':<10}{'Name':<20}{'Course':<15}{'Marks':<8}")
    print("-" * 53)
    for r in rows:
        print(f"{r[0]:<10}{r[1]:<20}{r[2]:<15}{r[3]:<8}")
    print()


def search_student():
    roll = input("Roll number to search: ").strip()
    conn = get_connection()
    row = conn.execute("SELECT * FROM students WHERE roll = ?",
                       (roll,)).fetchone()
    conn.close()
    if row:
        print(f"\nFound: {row[1]} | {row[2]} | Marks: {row[3]}\n")
    else:
        print("No student found.\n")


def update_student():
    roll = input("Roll number to update: ").strip()
    conn = get_connection()
    row = conn.execute("SELECT * FROM students WHERE roll = ?",
                       (roll,)).fetchone()
    if not row:
        print("No student found.\n")
        conn.close()
        return
    name = input(f"New name [{row[1]}]: ").strip() or row[1]
    course = input(f"New course [{row[2]}]: ").strip() or row[2]
    marks = input(f"New marks [{row[3]}]: ").strip() or row[3]
    conn.execute("UPDATE students SET name=?, course=?, marks=? WHERE roll=?",
                 (name, course, marks, roll))
    conn.commit()
    conn.close()
    print("Record updated!\n")


def delete_student():
    roll = input("Roll number to delete: ").strip()
    conn = get_connection()
    cur = conn.execute("DELETE FROM students WHERE roll = ?", (roll,))
    conn.commit()
    conn.close()
    if cur.rowcount:
        print("Record deleted!\n")
    else:
        print("No student found.\n")


def menu():
    while True:
        print("===== College Management System (SQLite) =====")
        print("1. Add  2. View  3. Search  4. Update  5. Delete  6. Exit")
        choice = input("Choose (1-6): ").strip()
        actions = {"1": add_student, "2": view_students,
                   "3": search_student, "4": update_student,
                   "5": delete_student}
        if choice == "6":
            print("Goodbye!")
            break
        action = actions.get(choice)
        if action:
            action()
        else:
            print("Invalid choice.\n")


if __name__ == "__main__":
    menu()
Bonus concept for your viva: notice the ? placeholders in every SQL query — that’s called a parameterized query, and it protects against SQL injection. Mentioning that unprompted is an easy way to impress an examiner.

Which Version Should You Use?

Your situation Use this version
Just learning / small assignment Version 1 — Console + JSON
Semester project with a demo Version 2 — Tkinter GUI
Final-year / want database marks Version 3 — SQLite
Maximum marks Combine 2 + 3 (GUI + database)

Line-by-Line: The Concepts This Project Teaches

If an examiner asks “explain your code,” here’s what each part demonstrates — learn these and you can defend every line:

  • Dictionaries & lists — each student is a dictionary; all students live in a list. This is Python’s bread-and-butter data modeling.
  • File handling / persistenceload_students() and save_students() show you understand that program memory disappears when the program closes, and data must be written to disk.
  • Functions with a single job — every menu option maps to one small function. That’s modular design, and it’s why the code is easy to extend.
  • Input validation — the duplicate roll-number check prevents corrupt data. Small detail, big marks.
  • The if __name__ == "__main__" guard — signals you know the difference between running a script and importing it as a module.
  • OOP (GUI version) — the CollegeApp class bundles state and behavior together, which is exactly what classes are for.
  • SQL CRUD (database version) — Create, Read, Update, Delete: the four operations behind virtually every real-world system.

Writing the Project Report (Structure That Works)

Most colleges expect a report alongside the code. Here’s a structure that fits this project — fill each section in your own words:

  • 1. Introduction — what the system does and who it’s for (admin staff managing student records).
  • 2. Problem statement — manual registers are slow, error-prone, and hard to search; this system automates it.
  • 3. Objectives — add/search/update/delete records, persistent storage, simple interface.
  • 4. Tools & technologies — Python 3, Tkinter (GUI), SQLite (database), JSON (file storage).
  • 5. System design — describe the menu flow or GUI layout; include a simple flowchart of the CRUD operations.
  • 6. Implementation — paste key code sections with short explanations (use the line-by-line section above).
  • 7. Testing — show a few test cases: adding a duplicate roll (rejected), searching a missing student (handled), updating a record (persists after restart).
  • 8. Future scope — attendance module, fee management, login system, web version with Flask.

Viva Questions Examiners Actually Ask (With Answers)

 

How to Make This Project Stand Out

Want top marks? Extend it with one or two of these:

  • Add a GUI with Tkinter so it has buttons and windows instead of a text menu.
  • Switch to a MySQL database instead of a JSON file to show database skills.
  • Add a login system for admin access.
  • Add more modules — courses, teachers, attendance, or fee records.

For ready-made practice, pair this with our Python projects with source code and free Python books.

More Python projects?

Grab 15 more Python projects with source code and free Python books on the blog.

Explore more on techprofree.com →

 

Frequently Asked Questions

Q: Why did you use a dictionary for each student?

Because a dictionary stores labeled fields (roll, name, course, marks) that can be accessed by name, which is clearer and safer than remembering list positions.

Q: What happens to the data when the program closes?

Nothing is lost — every change is written to the JSON file (or SQLite database) immediately, so the data persists between runs.

Q: Why SQLite instead of MySQL?

SQLite is serverless and built into Python — perfect for a single-user desktop app. MySQL would be the right choice for a multi-user, networked system, and migrating is straightforward because the SQL is nearly identical.

Q: What is the ? in your SQL queries?

A parameterized query placeholder. It keeps user input separate from the SQL command, which prevents SQL injection attacks.

Q: How would you scale this for a real college?

Move to a client-server model: a MySQL/PostgreSQL database, a web backend (Flask or Django), role-based logins, and modules for attendance, fees, and results.

Is this college management system good for a final-year project?

Yes — as a base. Add a Tkinter GUI or a MySQL database and a login system, and it’s strong enough for a final-year or semester submission.

Do I need to install anything to run it?

No. It uses only Python’s built-in features (json and os), so once Python 3 is installed you’re ready to go.

Can I add a database to this project?

Definitely. Replace the JSON file functions with MySQL or SQLite queries to store data in a real database — a great way to level up the project.

Is the source code free to use?

Yes, completely free. Copy it, modify it, and use it for your own learning or project submissions.

Which Python version do I need for this project?

Any Python 3 version works (3.8 or newer is ideal). The code uses only standard-library modules — json, os, tkinter, and sqlite3 — which ship with Python, so no pip installs are needed.

Can I run this project in VS Code or PyCharm?

Yes. Open the folder in VS Code or PyCharm, create the .py file, and run it from the built-in terminal. It also runs fine in IDLE or a plain command prompt — there’s no dependency on any specific editor.

How do I convert this into a web-based college management system?

Rebuild the interface with Flask or Django: keep the same database logic, expose each operation (add, search, update, delete) as a route, and render HTML templates instead of console menus. The SQLite version is the best starting point since the SQL carries over directly.

Can I add an admin login to this project?

Yes — store a username and a hashed password (use Python’s hashlib), ask for credentials before showing the menu, and only continue if they match. It’s a small addition that makes the project feel much more complete.

How do I add more fields like phone number or address?

Add the new keys to the student dictionary in the console/GUI versions (e.g. “phone”: phone), or add columns to the CREATE TABLE statement in the SQLite version. Then collect the extra input in add_student() and display it in view/search.

Why is my students.json file empty or corrupted?

This usually happens if the program was force-closed mid-write or the file was edited by hand and broke the JSON format. Delete students.json and run the program again — it recreates the file automatically. The SQLite version is more resistant to this.

What is the difference between this and a student management system?

They’re essentially the same core project — CRUD operations on student records. A full college management system usually adds more modules (courses, teachers, attendance, fees), which are listed in the Future Scope section and make great extensions.

How many lines of code is this project?

The console version is roughly 100 lines, the Tkinter GUI version about 120, and the SQLite version about 120. Combining GUI + database lands around 200–250 lines — a solid size for a semester submission.

Can I use this project for my resume or GitHub?

Definitely. Push it to GitHub with a README explaining the features and how to run it, and add a screenshot of the GUI version. Small, working, well-documented projects are exactly what recruiters like to see from students.

What should I name the project in my submission?

Something clear and specific works best, like “College Management System in Python using Tkinter and SQLite.” Naming the technologies signals what skills the project demonstrates before anyone even opens the code.