A comprehensive, role-based University Management System built with Django 6.0 and Bootstrap 5. It provides dedicated dashboards for Admins, Faculty, Students, and Accountants — covering academics, attendance, examinations, fees, timetables, and notices across 44+ screens.
Follow these steps to set up and run the University Management System on your local machine:
- Python 3.12+: Make sure Python is installed. You can check with
python --version. - pip: Python package manager (usually comes with Python).
# 1. Clone or Download the project
# If you have git:
git clone https://github.com/yourusername/UMS.git
cd UMS
# 2. Create a Virtual Environment
# This keeps the project dependencies separate from your system
python -m venv .venv
# 3. Activate the Virtual Environment
# Windows:
.venv\Scripts\activate
# macOS/Linux:
# source .venv/bin/activate
# 4. Install Dependencies
# This project requires Django, Pillow (for images), and xhtml2pdf (for PDFs)
pip install django pillow xhtml2pdf
# 5. Navigate to the project directory
cd ums
# 6. Apply Database Migrations
# This creates the necessary tables in the SQLite database
python manage.py migrate
# 7. Create a Superuser (Admin)
# We have a script for a quick setup (admin/adminpassword)
python create_superuser.py
# OR create your own manually:
# python manage.py createsuperuser
# 8. Run the Development Server
python manage.py runserver- Open your web browser and go to: http://127.0.0.1:8000/
- Admin Login: Use
adminas username andadminpasswordas password. - Once logged in, you can manage the entire university system from the dashboard.
- How to Run This Project
- Project Overview
- Technology Stack (with explanation)
- Project Architecture & Structure
- How Django Works (the basics)
- Settings File Explained
- URL Routing — How Pages Are Served
- Custom User Model & Authentication
- All Models Explained (Database Tables)
- All Views Explained (Business Logic)
- Forms Explained
- Templates & Frontend
- Utility Functions
- Admin Panel Configuration
- Role-Based Access Control
- Complete Data Flow Examples
- Database Relationships (ER Diagram in Text)
- PDF Generation
- Key Design Patterns Used
- Likely Viva Questions & Answers
UMS (University Management System) is a web-based application that manages all academic and administrative activities of a university. It is built using Django (Python) and provides separate dashboards for 4 types of users.
- Manages Students, Faculty, Departments, and Courses
- Handles Attendance marking and tracking
- Manages Examinations and Results
- Tracks Fee Payments and generates receipts
- Manages Timetables with clash detection
- Posts Notices targeted to specific audiences
- Generates PDF documents (transcripts, ID cards, receipts)
- Provides Global Search across the system
| Role | What they can do |
|---|---|
| Admin | Full control — CRUD on all entities, view reports, manage settings |
| Faculty | View their courses, mark attendance, upload marks, post notices, view reports |
| Student | View their courses, attendance, results, fees, timetable, notices; download PDFs |
The system has 44+ screens (HTML pages) distributed across the 4 roles.
| Technology | What it is | Why we use it |
|---|---|---|
| Python | A high-level programming language | Easy to read, large ecosystem, ideal for web development |
| Django 6.0.2 | A Python web framework (MVT pattern) | Provides built-in ORM, authentication, admin panel, routing, templating — everything needed for a web app |
| SQLite3 | A lightweight file-based relational database | Zero configuration, perfect for development/small projects. Data stored in db.sqlite3 file |
| xhtml2pdf | A Python library to convert HTML to PDF | Used to generate student transcripts, ID cards, fee receipts as downloadable PDFs |
| Pillow | Python Imaging Library | Required by Django's ImageField to handle profile image uploads |
| Technology | What it is | Why we use it |
|---|---|---|
| Django Template Engine | Server-side HTML rendering | Django renders HTML on the server before sending it to the browser. Uses {% %} and {{ }} syntax |
| Bootstrap 5 | CSS framework | Provides pre-built responsive UI components (buttons, cards, tables, forms, navigation) |
| Bootstrap Icons | Icon library | Provides icons (like sidebar icons, action buttons) |
This project does NOT use React, Angular, or Vue. Instead, Django itself generates the HTML pages on the server using its template engine, and Bootstrap provides the styling. This is called Server-Side Rendering (SSR).
Django follows the MVT pattern, which is similar to MVC:
┌───────────┐ ┌───────────┐ ┌───────────┐
│ MODEL │──────▶│ VIEW │──────▶│ TEMPLATE │
│ (Database)│ │ (Logic) │ │ (HTML) │
└───────────┘ └───────────┘ └───────────┘
│ ▲ │
│ │ │
└── stores data │ └── renders the
in tables handles requests final page
& passes data
- Model = Database table (defined in
models.py) - View = Business logic / controller (defined in
views.py) - Template = HTML page with Django tags (files in
templates/folder)
ums/ ← Root project folder
├── manage.py ← Django's command-line tool (runserver, migrate, etc.)
├── create_superuser.py ← Python script to auto-create admin user
├── db.sqlite3 ← The SQLite database FILE (all data is here)
│
├── ums/ ← Django PROJECT configuration folder
│ ├── settings.py ← All project settings (database, apps, middleware)
│ ├── urls.py ← ROOT URL router — connects URLs to apps
│ ├── wsgi.py ← Entry point for traditional web servers
│ └── asgi.py ← Entry point for async web servers
│
├── accounts/ ← APP: User authentication & custom user model
├── students/ ← APP: Student profiles, student panel views
├── faculty/ ← APP: Faculty profiles, teacher panel views
├── departments/ ← APP: Department CRUD
├── courses/ ← APP: Course CRUD & enrollment
├── attendance/ ← APP: Attendance sessions & records
├── examinations/ ← APP: Exams & results
├── fees/ ← APP: Fee structures, payments & accountant panel
├── timetable/ ← APP: Weekly schedule with clash detection
├── notices/ ← APP: Targeted announcements
├── core/ ← APP: Admin dashboard, settings, public pages, search
│
├── templates/ ← ALL HTML templates
│ ├── base.html ← Master layout for Admin panel
│ ├── student/ ← Student panel templates (8 pages)
│ ├── teacher/ ← Faculty panel templates (9 pages)
│ ├── accountant/ ← Accountant panel templates (6 pages)
│ ├── registration/ ← Login, password change/reset pages
│ ├── includes/ ← Reusable components (sidebar, navbar)
│ ├── common/ ← Public pages (about, contact)
│ └── [app_name]/ ← Admin-facing CRUD pages
│
├── static/ ← CSS, JavaScript, images (served by Django)
└── media/ ← User-uploaded files (profile pics, attachments)
Each folder like students/, faculty/, courses/ is a Django App — a self-contained module with its own:
models.py— Database tablesviews.py— Business logicurls.py— URL routesadmin.py— Django admin configurationapps.py— App configurationmigrations/— Database migration files (auto-generated)
| File | Purpose |
|---|---|
models.py |
Defines database tables as Python classes |
views.py |
Contains functions/classes that handle HTTP requests and return responses |
urls.py |
Maps URL patterns (like /students/list/) to view functions |
admin.py |
Registers models with Django's built-in admin panel |
apps.py |
App metadata (name, label) |
forms.py |
Custom form classes for data validation (only in examinations/ and timetable/) |
tests.py |
Unit tests (not used in this project) |
migrations/ |
Auto-generated files that track database schema changes |
When a user visits a URL (e.g., http://localhost:8000/students/list/), here's what happens:
1. Browser sends HTTP request to Django server
2. Django looks at ROOT_URLCONF (ums/urls.py)
3. ums/urls.py says: "students/ → include('students.urls')"
4. Django goes to students/urls.py
5. students/urls.py says: "list/ → views.student_list"
6. Django calls the student_list() function in students/views.py
7. The view function:
a. Queries the database using the ORM (models)
b. Puts data into a dictionary (context)
c. Passes context to a template (HTML file)
8. Django renders the template with the data
9. Returns the rendered HTML as an HTTP response
10. Browser displays the page
| Command | What it does |
|---|---|
python manage.py runserver |
Starts the development server on port 8000 |
python manage.py migrate |
Creates/updates database tables from migration files |
python manage.py makemigrations |
Generates migration files from model changes |
python manage.py createsuperuser |
Creates an admin user interactively |
python manage.py shell |
Opens Python shell with Django loaded |
File: ums/ums/settings.py
This is the brain of the Django project. Every configuration lives here.
BASE_DIR = Path(__file__).resolve().parent.parent
# ↑ Automatically calculates the project root directory
# Used to build file paths like BASE_DIR / 'templates'
SECRET_KEY = 'django-insecure-...'
# ↑ A unique secret key used for cryptographic signing
# (session cookies, CSRF tokens, password hashing)
# In production, this should be kept secret
DEBUG = True
# ↑ When True: shows detailed error pages, auto-reloads on code changes
# Must be False in production for security
INSTALLED_APPS = [
'django.contrib.admin', # Built-in admin panel
'django.contrib.auth', # Authentication system
'django.contrib.contenttypes', # Content type framework
'django.contrib.sessions', # Session management
'django.contrib.messages', # Flash messages
'django.contrib.staticfiles', # Static file serving
# Our Custom Apps (11 apps total):
'accounts', # Custom user model
'students', # Student management
'faculty', # Faculty management
'departments', # Department CRUD
'courses', # Course management
'attendance', # Attendance system
'examinations', # Exams & results
'fees', # Fee management
'timetable', # Timetable management
'core', # Dashboard, settings, public pages
'notices', # Notice board
]
AUTH_USER_MODEL = 'accounts.CustomUser'
# ↑ CRITICAL: Tells Django to use OUR CustomUser model instead of
# the default User model. This allows us to add 'role', 'phone', 'profile_image'
MIDDLEWARE = [...]
# ↑ Middleware = layers that process every request/response
# SecurityMiddleware: adds security headers
# SessionMiddleware: manages user sessions
# CsrfViewMiddleware: prevents Cross-Site Request Forgery attacks
# AuthenticationMiddleware: attaches user object to request
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# ↑ Using SQLite — a single-file database
# No server needed, data stored in db.sqlite3
TEMPLATES = [{
'DIRS': [BASE_DIR / 'templates'], # Where to find HTML templates
'APP_DIRS': True, # Also look in each app's templates/ folder
}]
STATIC_URL = 'static/'
STATICFILES_DIRS = [BASE_DIR / 'static']
# ↑ Static files (CSS, JS, images) served from /static/ URL
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
# ↑ User-uploaded files stored in media/ folder
LOGIN_REDIRECT_URL = 'dashboard_redirect'
# ↑ After login, redirect to this URL name (which then redirects by role)
LOGIN_URL = 'login'
# ↑ If user is not logged in, redirect them to this URL
LOGOUT_REDIRECT_URL = 'login'
# ↑ After logout, go back to login pageURLs are processed in two levels:
Level 1: Root URLs (ums/urls.py)
/ → core.urls (home, dashboard, settings, public pages)
/students/ → students.urls (student management & student panel)
/faculty/ → faculty.urls (faculty management & teacher panel)
/departments/ → departments.urls (department CRUD)
/courses/ → courses.urls (course CRUD & enrollment)
/notices/ → notices.urls (notice CRUD)
/attendance/ → attendance.urls (attendance list & detail)
/examinations/ → examinations.urls (exam CRUD & results)
/fees/ → fees.urls (fee management & accountant panel)
/timetable/ → timetable.urls (timetable CRUD)
/accounts/ → accounts.urls (login, logout, password)
/admin/ → Django admin site
Level 2: App-level URLs
| URL | View | Name | Purpose |
|---|---|---|---|
/accounts/login/ |
CustomLoginView |
login |
Login page with "Remember Me" |
/accounts/logout/ |
LogoutView |
logout |
Logout and redirect to login |
/accounts/dashboard/ |
dashboard_redirect |
dashboard_redirect |
Redirects to role-specific dashboard |
/accounts/profile/ |
profile |
profile |
View user profile |
/accounts/password-change/ |
MainPasswordChangeView |
password_change |
Change password (logged in) |
/accounts/password-change/done/ |
MainPasswordChangeDoneView |
password_change_done |
Password change success |
/accounts/password-reset/ |
PasswordResetView |
password_reset |
Forgot password form |
/accounts/password-reset/done/ |
PasswordResetDoneView |
password_reset_done |
Reset email sent |
/accounts/reset/<uidb64>/<token>/ |
PasswordResetConfirmView |
password_reset_confirm |
Set new password from email link |
/accounts/reset/done/ |
PasswordResetCompleteView |
password_reset_complete |
Password reset complete |
| URL | View | Name | Purpose |
|---|---|---|---|
/ |
home_redirect |
home |
Redirects to dashboard |
/dashboard/admin/ |
admin_dashboard |
admin_dashboard |
Admin dashboard with stats |
/settings/ |
settings_view |
settings |
University settings (name, logo, year) |
/about/ |
about_university |
about_university |
Public about page |
/contact/ |
contact_page |
contact_page |
Public contact form |
/profile/<username>/ |
public_profile |
public_profile |
Public profile of any user |
/search/ |
global_search |
global_search |
Search students, faculty, courses |
| URL | View | Name | Purpose |
|---|---|---|---|
/students/list/ |
student_list |
student_list |
Admin: List all students with filters |
/students/<pk>/ |
student_detail |
student_detail |
Admin: View student details |
/students/add/ |
add_student |
add_student |
Admin: Add new student |
/students/<pk>/edit/ |
edit_student |
edit_student |
Admin: Edit student |
/students/<pk>/delete/ |
delete_student |
delete_student |
Admin: Delete student |
/students/promote/ |
promote_students |
promote_students |
Admin: Promote to next semester |
/students/dashboard/ |
student_dashboard |
student_dashboard |
Student: Dashboard |
/students/courses/ |
student_my_courses |
student_my_courses |
Student: Enrolled courses |
/students/courses/<id>/ |
student_course_detail |
student_course_detail |
Student: Course details |
/students/attendance/ |
student_my_attendance |
student_my_attendance |
Student: Attendance records |
/students/timetable/ |
student_timetable |
student_timetable |
Student: Weekly timetable |
/students/results/ |
student_my_results |
student_my_results |
Student: Exam results |
/students/fees/ |
student_fee_status |
student_fee_status |
Student: Fee status |
/students/notices/ |
student_notices |
student_notices |
Student: Notices |
/students/profile/ |
student_profile |
student_profile |
Student: Edit profile |
/students/results/download/ |
download_results_pdf |
download_results_pdf |
Student: PDF transcript |
/students/id-card/download/ |
download_id_card_pdf |
download_id_card_pdf |
Student: PDF ID card |
/students/fee-receipt/download/<id>/ |
download_receipt_pdf |
download_receipt_pdf |
Student: PDF receipt |
| URL | View | Name | Purpose |
|---|---|---|---|
/faculty/list/ |
faculty_list |
faculty_list |
Admin: List all faculty |
/faculty/add/ |
add_faculty |
add_faculty |
Admin: Add faculty |
/faculty/<pk>/ |
faculty_detail |
faculty_detail |
Admin: Faculty details |
/faculty/<pk>/edit/ |
edit_faculty |
edit_faculty |
Admin: Edit faculty |
/faculty/<pk>/delete/ |
delete_faculty |
delete_faculty |
Admin: Delete faculty |
/faculty/dashboard/ |
teacher_dashboard |
teacher_dashboard |
Teacher: Dashboard |
/faculty/courses/ |
teacher_my_courses |
teacher_my_courses |
Teacher: Assigned courses |
/faculty/courses/<id>/students/ |
teacher_course_students |
teacher_course_students |
Teacher: Students in a course |
/faculty/attendance/ |
teacher_take_attendance |
teacher_take_attendance |
Teacher: Mark attendance |
/faculty/marks/ |
teacher_upload_marks |
teacher_upload_marks |
Teacher: Upload exam marks |
/faculty/marks/<id>/enter/ |
teacher_enter_marks |
teacher_enter_marks |
Teacher: Enter marks for exam |
/faculty/notices/ |
teacher_notices |
teacher_notices |
Teacher: View notices |
/faculty/notices/post/ |
teacher_post_notice |
teacher_post_notice |
Teacher: Post a notice |
/faculty/students/ |
teacher_view_students |
teacher_view_students |
Teacher: View students |
/faculty/students/<id>/profile/ |
teacher_student_profile |
teacher_student_profile |
Teacher: Student profile |
/faculty/reports/ |
teacher_reports |
teacher_reports |
Teacher: Performance/attendance reports |
/faculty/profile/ |
teacher_profile |
teacher_profile |
Teacher: Edit profile |
/faculty/timetable/ |
teacher_timetable |
teacher_timetable |
Teacher: Teaching schedule |
| URL | View | Name | Purpose |
|---|---|---|---|
/departments/list/ |
DepartmentListView |
department_list |
List departments |
/departments/add/ |
DepartmentCreateView |
department_add |
Add department |
/departments/<pk>/edit/ |
DepartmentUpdateView |
department_edit |
Edit department |
/departments/<pk>/delete/ |
DepartmentDeleteView |
department_delete |
Delete department |
| URL | View | Name | Purpose |
|---|---|---|---|
/courses/list/ |
CourseListView |
course_list |
List courses |
/courses/add/ |
CourseCreateView |
course_add |
Add course |
/courses/<pk>/edit/ |
CourseUpdateView |
course_edit |
Edit course |
/courses/<pk>/delete/ |
CourseDeleteView |
course_delete |
Delete course |
/courses/<pk>/enroll/ |
enroll_students |
course_enroll |
Enroll students into course |
| URL | View | Name | Purpose |
|---|---|---|---|
/attendance/list/ |
attendance_list |
attendance_list |
List attendance sessions |
/attendance/<pk>/detail/ |
attendance_detail |
attendance_detail |
View attendance for a session |
/attendance/export/ |
attendance_export |
attendance_export |
Export attendance as CSV |
| URL | View | Name | Purpose |
|---|---|---|---|
/examinations/list/ |
ExamListView |
exam_list |
List all exams |
/examinations/add/ |
ExamCreateView |
exam_add |
Schedule new exam |
/examinations/<pk>/edit/ |
ExamUpdateView |
exam_edit |
Edit exam |
/examinations/<pk>/delete/ |
ExamDeleteView |
exam_delete |
Delete exam |
/examinations/<pk>/results/ |
result_entry |
result_entry |
Enter marks for an exam |
/examinations/<pk>/sheet/ |
result_sheet |
result_sheet |
View result sheet |
/examinations/<pk>/publish/ |
publish_exam |
exam_publish |
Publish/unpublish results |
| URL | View | Name | Purpose |
|---|---|---|---|
/fees/structures/ |
FeeStructureListView |
fee_structure_list |
List fee structures |
/fees/structures/add/ |
FeeStructureCreateView |
fee_structure_add |
Add fee structure |
/fees/structures/<pk>/edit/ |
FeeStructureUpdateView |
fee_structure_edit |
Edit fee structure |
/fees/structures/<pk>/delete/ |
FeeStructureDeleteView |
fee_structure_delete |
Delete fee structure |
/fees/payments/ |
FeePaymentListView |
fee_payment_list |
List fee payments |
/fees/payments/add/ |
FeePaymentCreateView |
fee_payment_add |
Add payment |
/fees/payments/<id>/download/ |
download_receipt_admin |
fee_receipt_download_admin |
Download receipt PDF (admin) |
/fees/dashboard/ |
accountant_dashboard |
accountant_dashboard |
Accountant dashboard |
/fees/collect/ |
accountant_collect_fees |
accountant_collect_fees |
Collect fees from student |
/fees/history/ |
accountant_payment_history |
accountant_payment_history |
Payment history |
/fees/receipt/<id>/ |
accountant_receipt |
accountant_receipt |
View receipt |
/fees/reports/ |
accountant_reports |
accountant_reports |
Financial reports |
/fees/reports/export/ |
accountant_reports_export |
accountant_reports_export |
Export reports as CSV |
/fees/notices/ |
accountant_notices |
accountant_notices |
View notices |
/fees/notices/post/ |
accountant_post_notice |
accountant_post_notice |
Post a notice |
/fees/profile/ |
accountant_profile |
accountant_profile |
Edit profile |
| URL | View | Name | Purpose |
|---|---|---|---|
/timetable/list/ |
TimetableListView |
timetable_list |
List timetable entries |
/timetable/add/ |
TimetableCreateView |
timetable_add |
Add timetable entry |
/timetable/<pk>/edit/ |
TimetableUpdateView |
timetable_edit |
Edit entry |
/timetable/<pk>/delete/ |
TimetableDeleteView |
timetable_delete |
Delete entry |
| URL | View | Name | Purpose |
|---|---|---|---|
/notices/list/ |
NoticeListView |
notice_list |
List all notices |
/notices/add/ |
NoticeCreateView |
notice_add |
Create notice |
/notices/<pk>/delete/ |
NoticeDeleteView |
notice_delete |
Delete notice |
Django's default User model only has: username, email, password, first_name, last_name, is_staff, is_superuser, etc.
We needed extra fields: role, phone, profile_image. So we created a Custom User by extending AbstractUser.
class CustomUser(AbstractUser):
class Role(models.TextChoices):
ADMIN = "ADMIN", "Admin"
FACULTY = "FACULTY", "Faculty"
STUDENT = "STUDENT", "Student"
ACCOUNTANT = "ACCOUNTANT", "Accountant"
role = models.CharField(max_length=50, choices=Role.choices, default=Role.ADMIN)
phone = models.CharField(max_length=15, blank=True, null=True)
profile_image = models.ImageField(upload_to="profile_images/", blank=True, null=True)Key points:
- Inherits ALL fields from
AbstractUser(username, password, email, etc.) - Adds
role— determines which dashboard and permissions the user gets TextChoicesprovides an enum-like set of choices: ADMIN, FACULTY, STUDENT, ACCOUNTANTprofile_imageusesImageFieldwhich requires thePillowlibraryupload_to="profile_images/"means images are saved inmedia/profile_images/
-
Login Flow:
- User visits
/accounts/login/ CustomLoginViewprocesses the form- "Remember Me" checkbox: if unchecked, session expires when browser closes (
set_expiry(0)) - On success,
LOGIN_REDIRECT_URLsends user todashboard_redirect
- User visits
-
Dashboard Redirect:
def dashboard_redirect(request): user = request.user if user.role == 'ADMIN' or user.is_superuser: return redirect('admin_dashboard') elif user.role == 'FACULTY': return redirect('teacher_dashboard') elif user.role == 'STUDENT': return redirect('student_dashboard') elif user.role == 'ACCOUNTANT': return redirect('accountant_dashboard')
This function checks the user's
roleand sends them to the correct dashboard. -
Access Control Decorators: Each panel has a custom decorator that restricts access:
@admin_required— Only ADMIN role or superuser@faculty_required— Only users with a Faculty profile@student_required— Only users with a Student profile@accountant_required— Only ACCOUNTANT or ADMIN role
-
Password Change: Uses Django's built-in
PasswordChangeViewwith a mixin to pass the correct base template. -
Password Reset: Uses Django's built-in email-based password reset flow (4-step process).
Every model class → one database table.
Every class attribute → one column in that table.
Example: Student model → students_student table in SQLite.
| Field | Type | Purpose |
|---|---|---|
username |
CharField | Unique login username (inherited) |
password |
CharField | Hashed password (inherited) |
email |
EmailField | Email address (inherited) |
first_name |
CharField | First name (inherited) |
last_name |
CharField | Last name (inherited) |
role |
CharField (choices) | ADMIN / FACULTY / STUDENT / ACCOUNTANT |
phone |
CharField | Phone number |
profile_image |
ImageField | Profile picture |
Relationships: None (this is the root user model).
| Field | Type | Purpose |
|---|---|---|
name |
CharField(100) | Department name (e.g., "Computer Science") |
code |
CharField(10) unique | Short code (e.g., "CS") |
hod |
ForeignKey → Faculty | Head of Department |
Relationships:
hod→ ForeignKey toFaculty(meaning each department can have one HOD)on_delete=SET_NULLmeans if the HOD faculty is deleted, the field becomes NULL instead of deleting the department
| Field | Type | Purpose |
|---|---|---|
user |
OneToOneField → CustomUser | Links to the user account |
enrollment_no |
CharField(20) unique | Enrollment number (also used as username) |
department |
ForeignKey → Department | Which department |
semester |
IntegerField | Current semester (1–8) |
admission_date |
DateField | Date of admission |
Relationships:
user→ OneToOneField (each student has exactly ONE user account, and vice versa)department→ ForeignKey (many students can be in one department)
Important: When we access request.user.student, Django follows the OneToOneField to get the Student profile.
| Field | Type | Purpose |
|---|---|---|
user |
OneToOneField → CustomUser | Links to the user account |
department |
ForeignKey → Department | Faculty's department |
designation |
CharField(100) | Designation (e.g., "Professor", "Assistant Professor") |
joining_date |
DateField | Date of joining |
Relationships:
user→ OneToOneField to CustomUserdepartment→ ForeignKey to Department
| Field | Type | Purpose |
|---|---|---|
name |
CharField(100) | Course name (e.g., "Data Structures") |
code |
CharField(20) unique | Course code (e.g., "CS301") |
department |
ForeignKey → Department | Which department offers it |
faculty |
ForeignKey → Faculty | Who teaches it |
semester |
IntegerField | Which semester (determines eligible students) |
credits |
IntegerField | Credit hours |
capacity |
IntegerField | Max students (default 60) |
students |
ManyToManyField → Student | Enrolled students |
Relationships:
department→ ForeignKey (one department has many courses)faculty→ ForeignKey (one faculty teaches many courses)students→ ManyToManyField (many students can enroll in many courses)
ManyToMany explained: Django automatically creates a junction/intermediate table courses_course_students with columns course_id and student_id. This allows any number of students to be enrolled in any number of courses.
| Field | Type | Purpose |
|---|---|---|
course |
ForeignKey → Course | Which course |
date |
DateField | Date of the class |
marked_by |
ForeignKey → Faculty | Which faculty marked it |
Constraint: unique_together = ('course', 'date') — prevents duplicate attendance for the same course on the same date.
| Field | Type | Purpose |
|---|---|---|
attendance |
ForeignKey → Attendance | Links to the attendance session |
student |
ForeignKey → Student | Which student |
status |
BooleanField | True = Present, False = Absent |
How attendance works:
- One
Attendanceobject = one class session (course + date) - Many
AttendanceRecordobjects = one per student in that session - This is a one-to-many relationship (one session has many records)
| Field | Type | Purpose |
|---|---|---|
course |
ForeignKey → Course | Which course |
exam_type |
CharField (choices) | MID / FINAL / INTERNAL |
total_marks |
IntegerField | Maximum marks |
date |
DateField | Exam date |
start_time |
TimeField | Start time (optional) |
end_time |
TimeField | End time (optional) |
room_number |
CharField | Room (optional) |
is_published |
BooleanField | Whether results are visible to students |
is_published: When False, students cannot see results. When True, results are locked (faculty cannot edit marks).
| Field | Type | Purpose |
|---|---|---|
exam |
ForeignKey → Exam | Which exam |
student |
ForeignKey → Student | Which student |
marks_obtained |
DecimalField(5,2) | Marks scored (e.g., 87.50) |
Relationship: Links an Exam to a Student with their marks.
| Field | Type | Purpose |
|---|---|---|
department |
ForeignKey → Department | Which department |
semester |
IntegerField | Which semester |
amount |
DecimalField(10,2) | Fee amount |
Purpose: Defines how much a student in a specific department and semester should pay.
| Field | Type | Purpose |
|---|---|---|
student |
ForeignKey → Student | Who paid |
amount_paid |
DecimalField(10,2) | Amount paid |
payment_date |
DateField (auto_now_add) | Auto-set to today when created |
status |
CharField (choices) | PAID / PENDING |
payment_mode |
CharField (choices) | CASH / CHEQUE / ONLINE |
receipt_no |
CharField unique | Auto-generated receipt number |
collected_by |
ForeignKey → CustomUser | Which accountant collected it |
Auto-generated receipt: The save() method auto-generates receipt_no using UUID:
def save(self, *args, **kwargs):
if not self.receipt_no:
self.receipt_no = f"RCP-{uuid.uuid4().hex[:8].upper()}"
super().save(*args, **kwargs)| Field | Type | Purpose |
|---|---|---|
course |
ForeignKey → Course | Which course |
faculty |
ForeignKey → Faculty | Who teaches |
day_of_week |
CharField (choices) | Monday–Sunday |
start_time |
TimeField | Class start time |
end_time |
TimeField | Class end time |
room_number |
CharField | Room number |
| Field | Type | Purpose |
|---|---|---|
title |
CharField(200) | Notice title |
description |
TextField | Full notice content |
target_audience |
CharField (choices) | ALL / FACULTY / STUDENT |
target_course |
ForeignKey → Course | Optional course-specific notice |
attachment |
FileField | Optional uploaded file |
created_at |
DateTimeField (auto_now_add) | Auto-set timestamp |
posted_by |
ForeignKey → CustomUser | Who posted it |
| Field | Type | Purpose |
|---|---|---|
university_name |
CharField | University name |
logo |
ImageField | University logo |
academic_year |
CharField | e.g., "2024-2025" |
current_semester |
IntegerField | Current running semester |
Singleton Pattern: The save() method ensures only ONE instance ever exists:
def save(self, *args, **kwargs):
if not self.pk and UniversitySetting.objects.exists():
self.pk = UniversitySetting.objects.first().pk # Overwrite existing
super().save(*args, **kwargs)- Function-Based Views (FBV) — Regular Python functions decorated with
@login_required - Class-Based Views (CBV) — Django classes like
ListView,CreateView,UpdateView,DeleteView
- CBV used for simple CRUD (departments, courses, timetable, notices, fees) — less code
- FBV used for complex logic (attendance marking, fee collection, dashboards) — more flexibility
| View | Type | Purpose |
|---|---|---|
admin_dashboard |
FBV | Shows stats: total students, faculty, courses, revenue, attendance %, recent activities |
settings_view |
FBV | Manages university name, logo, academic year (singleton) |
about_university |
FBV | Public page showing university stats |
contact_page |
FBV | Contact form (displays success message) |
public_profile |
FBV | Shows any user's public profile |
global_search |
FBV | Searches Students, Faculty, Courses using Q objects |
custom_404 |
FBV | Custom 404 error page |
custom_403 |
FBV | Custom 403 forbidden page |
| View | Type | Purpose |
|---|---|---|
CustomLoginView |
CBV | Login with "Remember Me" — sets session expiry |
dashboard_redirect |
FBV | Checks role and redirects to correct dashboard |
profile |
FBV | Shows user profile page |
MainPasswordChangeView |
CBV | Password change with role-aware base template |
MainPasswordChangeDoneView |
CBV | Password change success page |
| View | Purpose | How it works |
|---|---|---|
student_list |
List all students | Queries Student.objects, supports filtering by department, semester, and search by name/enrollment |
student_detail |
Student's full details | Shows attendance %, results, fee status for a specific student |
add_student |
Create student | Creates CustomUser + Student objects, auto-generates password if needed |
edit_student |
Edit student | Updates user and student profile fields |
delete_student |
Delete student | Deletes user (cascades to student profile) |
promote_students |
Promote semester | Uses F('semester') + 1 to bulk increment selected students |
| View | Purpose | Key Logic |
|---|---|---|
student_dashboard |
Student home | Shows enrolled courses count, attendance %, pending fees, upcoming exams, recent results |
student_my_courses |
Enrolled courses | Queries courses where students=student |
student_course_detail |
Course detail | Shows attendance, results, schedule for one specific course |
student_my_attendance |
Attendance records | Course-wise attendance summary + detailed records with date filters |
student_my_results |
Exam results | Shows all results with filters; calculates average %, highest marks |
student_fee_status |
Fee status | Calculates total payable vs total paid → pending dues |
student_notices |
Notices | Shows notices targeted at ALL, STUDENT, or their enrolled courses |
student_timetable |
Weekly timetable | Organizes timetable entries by day of week |
student_profile |
Profile edit | Allows changing name, email, phone, profile image |
download_results_pdf |
PDF transcript | Generates PDF using render_to_pdf utility |
download_id_card_pdf |
PDF ID card | Generates student ID card PDF |
download_receipt_pdf |
PDF receipt | Generates fee receipt PDF for a specific payment |
| View | Purpose |
|---|---|
faculty_list |
List all faculty with department filter and search |
add_faculty |
Create user + faculty profile, auto-generate username and password |
faculty_detail |
View faculty details and assigned courses |
edit_faculty |
Update faculty information |
delete_faculty |
Delete faculty (cascades from user deletion) |
| View | Purpose | Key Logic |
|---|---|---|
teacher_dashboard |
Teacher home | Shows course count, student count, pending grading, today's schedule |
teacher_my_courses |
Assigned courses | Lists courses where faculty=faculty |
teacher_course_students |
Students in a course | Shows enrolled students for a course |
teacher_timetable |
Teaching schedule | Organizes by day of week |
teacher_take_attendance |
Mark attendance | GET: loads student list; POST: creates Attendance + AttendanceRecord |
teacher_upload_marks |
View exams | Lists exams for faculty's courses |
teacher_enter_marks |
Enter marks | Creates/updates Result objects; blocked if exam is published |
teacher_notices |
View notices | Shows notices posted by self or targeted at ALL/FACULTY |
teacher_post_notice |
Post notice | Creates Notice object with optional course targeting |
teacher_view_students |
All students | Shows students across all assigned courses |
teacher_student_profile |
Student profile | Shows attendance + results for a specific student in faculty's courses |
teacher_reports |
Reports | Generates attendance or performance reports for a course |
teacher_profile |
Profile edit | Allows editing personal info |
| View | Type | Django Generic View |
|---|---|---|
DepartmentListView |
CBV | ListView — auto-queries all departments |
DepartmentCreateView |
CBV | CreateView — auto-generates form and saves |
DepartmentUpdateView |
CBV | UpdateView — auto-loads, edits, saves |
DepartmentDeleteView |
CBV | DeleteView — confirms and deletes |
CourseListView/Create/Update/Delete |
CBV | Same pattern as departments |
enroll_students |
FBV | Shows eligible students (same dept + semester), adds them via course.students.add() |
| View | Purpose |
|---|---|
attendance_list |
Lists attendance sessions with role-based filtering |
attendance_detail |
Shows individual records (who was present/absent) |
attendance_export |
Exports attendance as CSV file |
| View | Type | Purpose |
|---|---|---|
ExamListView |
CBV | List all exams |
ExamCreateView |
CBV | Schedule new exam (uses ExamForm) |
ExamUpdateView |
CBV | Edit exam |
ExamDeleteView |
CBV | Delete exam |
result_entry |
FBV | Enter marks for all students in an exam |
result_sheet |
FBV | View result sheet for an exam |
publish_exam |
FBV | Toggle is_published flag |
| View | Purpose | Key Logic |
|---|---|---|
accountant_dashboard |
Dashboard | Total collected, pending, monthly bar chart, recent payments |
accountant_collect_fees |
Collect fees | Search student → show fee info → record payment with overpayment validation |
accountant_payment_history |
History | Searchable and filterable payment list |
accountant_receipt |
View receipt | Shows formatted receipt for a payment |
accountant_reports |
Financial reports | Monthly, Annual, Department-wise reports |
accountant_reports_export |
Export CSV | Exports financial reports as CSV |
accountant_notices |
View notices | Filter by ALL or own notices |
accountant_post_notice |
Post notice | Create notice |
download_receipt_admin |
PDF receipt | Generate PDF receipt |
accountant_profile |
Profile edit | Edit personal info |
Forms validate user input before saving to database. Django can auto-generate forms from models.
class ExamForm(forms.ModelForm):
class Meta:
model = Exam
fields = ['course', 'exam_type', 'total_marks', 'date',
'start_time', 'end_time', 'room_number', 'is_published']
widgets = {
'date': forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}),
'start_time': forms.TimeInput(attrs={'type': 'time', 'class': 'form-control'}),
...
}ModelFormauto-generates form fields from theExammodelwidgetsdictionary customizes how each field renders (HTML attributes)'type': 'date'gives a native date picker in the browser
class TimetableForm(forms.ModelForm):
def clean(self):
# Validates 3 things:
# 1. End time must be after start time
# 2. Faculty is not double-booked (same day, overlapping time)
# 3. Room is not double-booked
# 4. Course is not double-scheduled
overlap_query = Timetable.objects.filter(
day_of_week=day,
start_time__lt=end, # existing starts before new ends
end_time__gt=start # existing ends after new starts
)clean()is called automatically during form validation- Uses overlap detection: checks if
existing.start < new.end AND existing.end > new.start - Prevents scheduling conflicts for faculty, rooms, and courses
templates/
├── base.html ← Admin panel master layout
├── student/
│ └── base_student.html ← Student panel master layout
├── teacher/
│ └── base_teacher.html ← Teacher panel master layout
├── accountant/
│ └── base_accountant.html ← Accountant panel master layout
├── includes/
│ ├── sidebar.html ← Admin sidebar navigation
│ └── navbar.html ← Top navbar with search, profile
└── registration/
├── login.html ← Login page
└── password_change_form.html ← Password change page
Django uses template inheritance to avoid repeating HTML:
base.html (master layout)
│
├── {% block title %}{% endblock %} ← Page title
├── {% block extra_css %}{% endblock %} ← Extra CSS
├── {% include 'includes/sidebar.html' %} ← Sidebar
├── {% include 'includes/navbar.html' %} ← Navbar
├── {% block content %}{% endblock %} ← Main content
└── {% block extra_js %}{% endblock %} ← Extra JS
Child templates "extend" the base:
{% extends "base.html" %}
{% block content %}
<h1>Student List</h1>
...actual page content...
{% endblock %}| Tag | Purpose | Example |
|---|---|---|
{% extends %} |
Inherit from parent template | {% extends "base.html" %} |
{% block %} |
Define overridable sections | {% block content %}...{% endblock %} |
{% include %} |
Include another template | {% include 'includes/sidebar.html' %} |
{{ variable }} |
Output a variable | {{ student.enrollment_no }} |
{% for %} |
Loop | {% for s in students %}...{% endfor %} |
{% if %} |
Conditional | {% if user.role == 'ADMIN' %}...{% endif %} |
{% url 'name' %} |
Generate URL from name | {% url 'student_detail' pk=student.id %} |
{% csrf_token %} |
CSRF protection token | Required inside every <form> |
{% load %} |
Load template tag library | {% load core_extras %} |
{{ form.field|addclass:"form-control" }} |
Custom filter | Adds CSS class to form field |
{% messages %} |
Display flash messages | Success/error notifications |
-
addclassfilter: Adds a CSS class to a form field widget{{ form.email|addclass:"form-control" }} -
get_itemfilter: Gets a value from a dictionary by key{{ my_dict|get_item:key }}
def render_to_pdf(template_src, context_dict={}):
template = get_template(template_src) # Load HTML template
html = template.render(context_dict) # Render with data
result = BytesIO() # In-memory buffer
pdf = pisa.pisaDocument( # Convert HTML → PDF
BytesIO(html.encode("UTF-8")), result
)
if not pdf.err:
return HttpResponse(result.getvalue(), content_type='application/pdf')
return None- Uses xhtml2pdf library (alias:
pisa) - Takes a Django template path and context data
- Renders HTML first, then converts to PDF
- Returns PDF as HTTP response with
application/pdfcontent type
def log_activity(user, obj, action_flag, message=''):
LogEntry.objects.log_action(
user_id=user.pk,
content_type_id=ContentType.objects.get_for_model(obj).pk,
object_id=obj.pk,
object_repr=str(obj),
action_flag=action_flag,
change_message=message
)- Logs admin activities to Django's built-in
LogEntrytable - Used to show "Recent Activities" on admin dashboard
content_type_idtells Django what type of object was modified
Django automatically provides a /admin/ web interface for managing database records. We customize it in each app's admin.py.
@admin.register(CustomUser)
class CustomUserAdmin(UserAdmin):
list_display = ('username', 'email', 'first_name', 'last_name', 'role', 'is_staff')
list_filter = ('role', 'is_staff', 'is_active')
search_fields = ('username', 'email', 'first_name', 'last_name')
fieldsets = UserAdmin.fieldsets + (
('Extra Info', {'fields': ('role', 'phone', 'profile_image')}),
)list_display— columns shown in the list viewlist_filter— sidebar filterssearch_fields— searchable columnsfieldsets— adds our custom fields to the edit form
@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
list_display = ('enrollment_no', 'user', 'department', 'semester', 'admission_date')
list_filter = ('department', 'semester')
raw_id_fields = ('user',) # Shows user selection as ID input, not dropdown@admin.register(Course)
class CourseAdmin(admin.ModelAdmin):
filter_horizontal = ('students',) # Nice widget for ManyToMany selectionclass UniversitySettingAdmin(admin.ModelAdmin):
def has_add_permission(self, request):
if UniversitySetting.objects.exists():
return False # Can't add more than one
return super().has_add_permission(request)| Mechanism | Where Used | How It Works |
|---|---|---|
@login_required |
All views | Django decorator — redirects to login if not authenticated |
@admin_required |
Core app views | Custom decorator — checks role == 'ADMIN' or is_superuser |
@faculty_required |
Faculty panel views | Custom decorator — checks hasattr(user, 'faculty') |
@student_required |
Student panel views | Custom decorator — checks hasattr(user, 'student') |
@accountant_required |
Accountant panel views | Custom decorator — checks role in ('ACCOUNTANT', 'ADMIN') |
LoginRequiredMixin |
CBVs | Class-based equivalent of @login_required |
UMBaseTemplateMixin |
Password change views | Determines correct base template by role |
def student_required(view_func):
@login_required
def wrapper(request, *args, **kwargs):
if not hasattr(request.user, 'student'):
messages.error(request, 'Access denied. Student account required.')
return redirect('login')
return view_func(request, *args, **kwargs)
return wrapper- First,
@login_requiredensures user is logged in - Then checks if user has a
studentattribute (OneToOneField creates this) - If yes, allows access. If no, shows error and redirects to login.
| URL Pattern | Who Can Access |
|---|---|
/dashboard/admin/ |
Admin only |
/students/dashboard/ |
Students only |
/faculty/dashboard/ |
Faculty only |
/fees/dashboard/ |
Accountant or Admin |
/departments/, /courses/, /examinations/, /timetable/, /notices/ |
Any logged-in user (admin-facing) |
/about/, /contact/ |
Anyone (public) |
/students/list/, /faculty/list/ |
Any logged-in user (meant for admin) |
1. Admin clicks "Add Student" → GET /students/add/
2. Django calls add_student() view
3. View renders add_student.html with department list
4. Admin fills the form and clicks Submit → POST /students/add/
5. View receives POST data:
- Creates CustomUser with role=STUDENT
- Sets password (auto-generated or manual)
- Uploads profile image if provided
- Creates Student object linked to USER via OneToOneField
- Logs the activity using log_activity()
6. Redirects to /students/list/ with success message
1. Faculty goes to /faculty/attendance/ (GET)
2. teacher_take_attendance() shows courses taught by this faculty
3. Faculty selects a course and date → GET /faculty/attendance/?course=5&date=2026-02-20
4. View loads enrolled students for that course
5. View checks if attendance already exists for that date (unique_together constraint)
6. Faculty checks checkboxes for present students → POST
7. View creates:
a. Attendance object (course + date + marked_by)
b. AttendanceRecord per student (status=True/False)
8. If attendance already existed, old records are deleted and recreated
9. Redirects with success message
1. Accountant visits /fees/collect/
2. Searches for student by name or enrollment number
3. View shows matching students
4. Accountant selects a student → loads fee info:
- Total payable (from FeeStructure matching department + semester)
- Total paid so far (sum of PAID FeePayments)
- Pending dues = total payable - total paid
5. Accountant enters amount and payment mode → POST
6. View validates:
- Amount > 0
- Amount ≤ pending dues (prevents overpayment)
7. Creates FeePayment with:
- Auto-generated receipt_no (RCP-XXXXXXXX)
- collected_by = current user
- status = PAID
8. Redirects to receipt page showing the payment details
1. Student visits /students/results/
2. student_my_results() view:
a. Gets student from request.user.student (OneToOneField)
b. Queries Result objects where student=this_student
c. Filters by course and exam_type if specified
d. Calculates summary: total exams, avg %, highest, passed count
3. Renders student/my_results.html with results list and summary
4. Student can also click "Download PDF" → /students/results/download/
5. download_results_pdf() generates PDF using xhtml2pdf
1. Admin visits /timetable/add/
2. TimetableCreateView shows form (TimetableForm)
3. Admin fills: course, faculty, day, start_time, end_time, room
4. On submit, TimetableForm.clean() runs validation:
a. Checks end_time > start_time
b. Queries existing timetables for same day with overlapping times
c. Checks if selected faculty is already busy → Error
d. Checks if selected room is already booked → Error
e. Checks if course is already scheduled → Error
5. If no clashes: saves and redirects with success
6. If clash detected: shows form with specific error messages
┌──────────────┐
│ CustomUser │
│──────────────│
│ username │
│ password │
│ email │
│ role │
│ phone │
│ profile_image│
└──────┬───┬──┘
1:1 ↙ ↘ 1:1
┌──────────┐ ┌──────────┐
│ Student │ │ Faculty │
│──────────│ │──────────│
│enroll_no │ │designat. │
│semester │ │join_date │
│admission │ └────┬─────┘
└────┬─────┘ │
│ │ FK
FK ↙ │ M2M ↓
┌────────────┐ │ ┌──────────┐
│ Department │←─┼────FK───│ Course │
│────────────│ │ │──────────│
│ name │ └────────▶│ students │←── M2M
│ code │ │ faculty │←── FK
│ hod ──────FK──────────▶ │ semester │
└────────────┘ └────┬─────┘
│ FK
┌────────────────┼────────────────┐
↓ ↓ ↓
┌──────────────┐ ┌──────────┐ ┌───────────┐
│ Attendance │ │ Exam │ │ Timetable │
│──────────────│ │──────────│ │───────────│
│ course (FK) │ │course FK │ │ course FK │
│ date │ │ type │ │faculty FK │
│ marked_by FK │ │ marks │ │ day │
└──────┬───────┘ │is_publis.│ │ time │
│ └────┬─────┘ │ room │
↓ ↓ └───────────┘
┌────────────────┐ ┌──────────┐
│AttendanceRecord│ │ Result │
│────────────────│ │──────────│
│ attend. (FK) │ │ exam FK │
│ student (FK) │ │student FK│
│ status (bool) │ │ marks │
└────────────────┘ └──────────┘
┌───────────────┐ ┌───────────────┐ ┌────────────────┐
│ FeeStructure │ │ FeePayment │ │ Notice │
│───────────────│ │───────────────│ │────────────────│
│ dept (FK) │ │ student (FK) │ │ title │
│ semester │ │ amount │ │ description │
│ amount │ │ status │ │ target_audience│
└───────────────┘ │ mode │ │ target_course │
│ receipt_no │ │ attachment │
│ collected_by │ │ posted_by (FK) │
└───────────────┘ └────────────────┘
┌──────────────────┐
│UniversitySetting │ (Singleton — only 1 row)
│──────────────────│
│ university_name │
│ logo │
│ academic_year │
│ current_semester │
└──────────────────┘
| Relationship | Type | Meaning |
|---|---|---|
| CustomUser ↔ Student | One-to-One | Each student has exactly one user account |
| CustomUser ↔ Faculty | One-to-One | Each faculty has exactly one user account |
| Department → Faculty (hod) | FK (Many-to-One) | A department has one HOD |
| Student → Department | FK | Many students belong to one department |
| Faculty → Department | FK | Many faculty belong to one department |
| Course → Department | FK | Many courses belong to one department |
| Course → Faculty | FK | Many courses are taught by one faculty |
| Course ↔ Student | Many-to-Many | Many students enroll in many courses |
| Attendance → Course | FK | Many attendance sessions per course |
| AttendanceRecord → Attendance | FK | Many records per session |
| AttendanceRecord → Student | FK | Many records per student |
| Exam → Course | FK | Many exams per course |
| Result → Exam + Student | FK + FK | Links exam to student with marks |
| FeeStructure → Department | FK | Fee rates per department |
| FeePayment → Student | FK | Many payments per student |
| Notice → CustomUser (posted_by) | FK | Who posted the notice |
| Notice → Course (target_course) | FK | Optional course targeting |
| Timetable → Course + Faculty | FK + FK | Schedule entry |
- Library used:
xhtml2pdf(imported aspisa) - Process:
HTML Template → Django renders with data → xhtml2pdf converts to PDF → HTTP Response - Function:
render_to_pdf()incore/utils.py
| Template | Generated By | |
|---|---|---|
| Student Transcript | student/my_results_pdf.html |
download_results_pdf view |
| Student ID Card | student/id_card_pdf.html |
download_id_card_pdf view |
| Fee Receipt (Student) | student/receipt_pdf.html |
download_receipt_pdf view |
| Fee Receipt (Admin) | student/receipt_pdf.html |
download_receipt_admin view |
expire_year = student.admission_date.year + 4
expire_date = student.admission_date.replace(year=expire_year)ID card is valid for 4 years from admission date.
Only one configuration record exists. The save() method overwrites the existing record.
Custom decorators (admin_required, faculty_required, etc.) wrap view functions to add access control logic.
base.html provides common layout. All pages extend it and override specific blocks.
A class that adds role-aware base_template context to CBVs. Used with password change views.
Django's ORM abstracts database queries. Instead of SQL, we write Python:
# Instead of: SELECT * FROM students WHERE department_id = 1
Student.objects.filter(department_id=1)
# Instead of: SELECT COUNT(*) FROM attendance_record WHERE status = 1
AttendanceRecord.objects.filter(status=True).count()receipt_no = f"RCP-{uuid.uuid4().hex[:8].upper()}"Uses UUID (Universally Unique Identifier) to generate unique receipt numbers like RCP-A1B2C3D4.
This project is for educational purposes.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
