A complete, production-ready Django web application for academic analytics with role-based access control, interactive Google Charts dashboards, CSV/Excel import, PDF reports, and email notifications.
- Python 3.10+ installed
- pip (Python package manager)
cd edupulse/# Windows
python -m venv venv
venv\Scripts\activate
# macOS / Linux
python3 -m venv venv
source venv/bin/activatepip install -r requirements.txtpython manage.py migratepython manage.py create_demo_dataThis creates:
| Role | Username | Password |
|---|---|---|
| Admin | admin | admin123 |
| Faculty | faculty1 | faculty123 |
| HOD | hod1 | hod123 |
| Student | alice21 | student123 |
| Student | bob21 | student123 |
| Student | carol21 | student123 |
python manage.py collectstatic --noinputpython manage.py runserverOpen http://127.0.0.1:8000 in your browser.
edupulse/
β
βββ edupulse/ # Django project config
β βββ settings.py # All settings (DB, email, static, etc.)
β βββ urls.py # Root URL dispatcher
β βββ wsgi.py
β
βββ accounts/ # Authentication + RBAC
β βββ models.py # Profile model (extends User)
β βββ views.py # Login, logout, user CRUD
β βββ forms.py # Login, register, profile forms
β βββ decorators.py # @role_required, @admin_required, etc.
β βββ urls.py
β
βββ results/ # Core academic data
β βββ models.py # Batch, Subject, Result, UploadLog
β βββ views.py # Upload, list, edit, export (CSV/PDF)
β βββ forms.py # Upload form, filter form, manual entry
β βββ utils.py # CSV/Excel parser + validator
β βββ urls.py
β
βββ analytics/ # Charts and dashboards
β βββ views.py # Dashboard views + JSON chart endpoints
β βββ urls.py
β
βββ core/ # Shared utilities
β βββ views.py # Role-based dashboard router
β βββ signals.py # Email alert on low performance
β βββ apps.py # Registers signals
β βββ management/
β βββ commands/
β βββ create_demo_data.py
β
βββ templates/ # All HTML templates
β βββ base.html # Master layout with sidebar
β βββ accounts/
β βββ results/
β βββ analytics/
β βββ core/
β
βββ static/
β βββ css/main.css # Custom design system
β βββ js/main.js # Google Charts loader + sidebar JS
β βββ sample_results.csv # Sample upload file
β
βββ media/ # Uploaded files (runtime)
βββ manage.py
βββ requirements.txt
| Feature | Admin | Faculty | HOD | Student |
|---|---|---|---|---|
| Upload CSV/Excel | β | β | β | β |
| Add result manually | β | β | β | β |
| View all results | β | β | β | β |
| Delete results | β | β | β | β |
| Institution analytics | β | β | β | β |
| Subject analysis | β | β | β | β |
| View own results only | β | β | β | β |
| Download personal PDF | β | β | β | β |
| Manage users | β | β | β | β |
| Manage subjects/batches | β | β | β | β |
| Upload logs | β | β | β | β |
| Export CSV (all results) | β | β | β | β |
| Export PDF (all results) | β | β | β | β |
Your file must contain these exact column headers (row 1):
roll_number, subject_code, semester, batch_name, marks_obtained, remarks
roll_numberβ must match a student profile's roll numbersubject_codeβ must match an existing subject code (e.g. CS301)semesterβ integer 1β10batch_nameβ must match an existing batch name (e.g. 2021-2025)marks_obtainedβ float 0β100remarksβ optional free text
A sample file is available at /static/sample_results.csv.
- File is parsed row by row
- Each row is validated (missing fields, invalid marks, unknown roll numbers, duplicates)
- Valid rows are saved; errors are displayed in a detailed error report
- An
UploadLogaudit entry is created for every upload - If a student fails, an email alert is sent automatically (if email is configured)
All charts are live and filterable via AJAX β no page reload needed.
| Chart Type | Data Shown | Filters Available |
|---|---|---|
| Pie Chart | Overall Pass vs Fail | Semester, Batch |
| Column Chart | Grade distribution (O/A+/A/β¦/F) | Semester, Subject |
| Line Chart | Average marks per semester | Batch, Subject |
| Bar Chart | Average marks per subject | Semester, Batch |
| Scatter Plot | Individual student performance | Semester, Subject |
| Line Chart | Personal semester trend (student) | β (auto-filtered by user) |
Email uses Django's console backend by default (prints to terminal).
To send real emails, update edupulse/settings.py:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'your-gmail@gmail.com'
EMAIL_HOST_PASSWORD = 'your-app-password' # Gmail App Password (not regular password)Email alerts fire automatically when:
- A student result is uploaded with
is_pass = False
- URL:
/results/export/csv/ - Supports filter query params:
?semester=3&batch=1&subject=2 - Downloads instantly as
results_export.csv
- URL:
/results/export/pdf/ - Generated with ReportLab
- Students get their own results only
- Staff get full institution report
- Downloads as
edupulse_report.pdf
Custom decorators in accounts/decorators.py:
from accounts.decorators import (
role_required, # @role_required('admin', 'hod')
admin_required, # @admin_required
faculty_required, # @faculty_required (admin + faculty)
hod_required, # @hod_required (admin + hod)
staff_required, # @staff_required (admin + faculty + hod)
student_required, # @student_required
)Usage:
@staff_required
def my_view(request):
...role: admin | faculty | hod | studentdepartment,phone,roll_number,bio- Auto-created via
post_savesignal on User
name,department,start_year,end_year- Unique constraint:
(name, department)
code(unique),name,department,semestermax_marks(default 100),pass_marks(default 40),credits
- FK to:
student(User),subject,batch marks_obtained,semester- Auto-calculated:
grade(O/A+/A/B+/B/C/F),is_pass - Unique constraint:
(student, subject, semester, batch)β no duplicates
- Audit trail: file name, uploader, total/success/error rows, status, timestamp
After running create_demo_data:
- Admin view: Login as
admin/admin123β full dashboard with all 4 charts - Upload test: Go to Results β Upload β upload
static/sample_results.csv - Filter test: Results list β apply semester/batch/grade filters
- Analytics: Analytics β Institution β use dropdown filters to refresh charts live
- Student view: Login as
alice21/student123β personal trend chart + results table - PDF report: Any role β Results β Export PDF
- Add to
Profile.ROLE_CHOICESinaccounts/models.py - Add a decorator in
accounts/decorators.py - Add a case in
core/views.py β dashboard() - Create a template:
templates/core/dashboard_<role>.html - Update sidebar in
templates/base.html
Edit Subject.pass_marks default in results/models.py.
Or update per-subject via Admin or the Subjects management page.
Edit Result.calculate_grade() in results/models.py.
# Create demo data (first time setup)
python manage.py create_demo_data
# Create a superuser manually
python manage.py createsuperuser
# Make + apply migrations after model changes
python manage.py makemigrations
python manage.py migrate
# Open Django shell
python manage.py shell
# Collect static files for production
python manage.py collectstatic- Set
DEBUG = Falseinsettings.py - Set a strong
SECRET_KEY - Configure
ALLOWED_HOSTS - Use PostgreSQL instead of SQLite for production
- Use Gunicorn + Nginx
- Set
EMAIL_BACKENDto SMTP - Run
collectstaticand serve/staticfiles/via Nginx
| Package | Version | Purpose |
|---|---|---|
| Django | β₯ 4.2 | Web framework |
| openpyxl | β₯ 3.1 | Excel (.xlsx) file parsing |
| reportlab | β₯ 4.0 | PDF report generation |
| Pillow | β₯ 10.0 | Image handling (avatars) |
- SQLite3: Zero-config default β swap to PostgreSQL for production
- Class vs Function views: Functions used throughout for simplicity and decorator clarity
- Google Charts via AJAX: All chart data served as JSON from dedicated endpoints β decoupled from page renders
- Signal-based emails: Low-performance alerts fire via Django signals β no manual calls in views
- Two-stage upload: Parse β show errors β save atomically β prevents partial bad data
- Auto-grade calculation:
Result.save()computes grade and pass/fail β never stored manually
Built with Django 4.2, Bootstrap 5, Google Charts β EduPulse Β© 2024