This commit is contained in:
sankalp committed 2025-01-16 13:16:44 +05:45
1 parent 7c09b319aa
commit edb0f45871
105 files changed
-19786

No files matched your search

View File
Whitespace-only changes.
-333
View File
@@ -1,333 +0,0 @@
from django.contrib import admin
from app.models import (
Teacher,
Student,
Staff,
Course,
AcademicYear,
Subject,
NewsEvent,
Attendance,
Marksheet,
Library,
Marksheet,
# Certificate,
SubjectMark,
)
from django.shortcuts import render
from django.urls import path
from django.template.response import TemplateResponse
# BaseUserAdmin to handle common behavior for BaseUser-based models
class BaseUserAdmin(admin.ModelAdmin):
exclude = ["user"]
def save_model(self, request, obj, form, change):
super().save_model(request, obj, form, change)
if obj.user:
obj.user.groups.set(obj.group.all())
obj.user.save()
@admin.register(Teacher)
class TeacherAdmin(admin.ModelAdmin):
list_display = ("first_name", "last_name", "email", "phone", "gender", "qualification", "specialization")
search_fields = ("first_name", "last_name", "email", "phone", "specialization")
list_filter = ("gender", "qualification", "date_of_joining")
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path("", self.teacher_list_view, name="teacher_changelist"),
]
return custom_urls + urls
def teacher_list_view(self, request):
teachers = Teacher.objects.all()
context = {
**self.admin_site.each_context(request),
"title": "Teacher List",
"teachers": teachers,
"opts": self.model._meta,
}
return TemplateResponse(request, "Hod/teacher.html", context)
@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
list_display = ("first_name", "last_name", "email", "phone", "course", "academic_year")
search_fields = ("first_name", "last_name", "email", "phone", "course__name")
list_filter = ("gender", "academic_year", "course")
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path("", self.student_list_view, name="student_changelist"),
]
return custom_urls + urls
def student_list_view(self, request):
students = Student.objects.select_related("course", "academic_year").all()
context = {
**self.admin_site.each_context(request),
"title": "Student List",
"students": students,
"opts": self.model._meta,
}
return TemplateResponse(request, "Hod/student.html", context)
@admin.register(Staff)
class StaffAdmin(admin.ModelAdmin):
list_display = ("first_name", "last_name", "email", "position", "date_of_joining")
search_fields = ("first_name", "last_name", "email", "position")
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path("", self.staff_list_view, name="staff_list"),
]
return custom_urls + urls
def staff_list_view(self, request):
staff_members = Staff.objects.all()
context = {
**self.admin_site.each_context(request),
"title": "Staff List",
"staff_members": staff_members,
}
return TemplateResponse(request, "Hod/staff.html", context)
@admin.register(Course)
class CourseAdmin(admin.ModelAdmin):
list_display = ("name", "level", "course_type", "duration")
list_filter = ("level", "course_type")
search_fields = ("name",)
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path("", self.course_list_view, name="course_changelist"),
]
return custom_urls + urls
def course_list_view(self, request):
# Get all courses
courses = Course.objects.all().order_by("name")
# Prepare the context with your model's specific fields
context = {
**self.admin_site.each_context(request),
"title": "Course List",
"courses": courses,
"opts": self.model._meta,
"has_add_permission": self.has_add_permission(request),
"level_choices": dict(Course.level_choice),
"course_type_choices": dict(
[("semester", "Semester-based"), ("yearly", "Yearly-based")]
),
}
return TemplateResponse(request, "Hod/add_course.html", context)
@admin.register(AcademicYear)
class AcademicYearAdmin(admin.ModelAdmin):
list_display = ("id", "year")
search_fields = ("year",)
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path("", self.academic_year_list_view, name="academic_year_changelist"),
]
return custom_urls + urls
def academic_year_list_view(self, request):
# Get all academic years
academic_years = AcademicYear.objects.all().order_by("year")
# Prepare the context with your model's specific fields
context = {
**self.admin_site.each_context(request),
"title": "Academic List",
"academic_years": academic_years,
"opts": self.model._meta,
"has_add_permission": self.has_add_permission(request),
}
return TemplateResponse(request, "Hod/academic_year.html", context)
@admin.register(Subject)
class SubjectAdmin(admin.ModelAdmin):
list_display = ("name", "course", "semester_or_year_number", "teacher")
search_fields = ("name", "course__name", "teacher__name")
list_filter = ("course", "semester_or_year_number")
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path("", self.subject_list_view, name="subject_changelist"),
]
return custom_urls + urls
def subject_list_view(self, request):
subjects = Subject.objects.select_related("course", "teacher").all().order_by("course__name", "semester_or_year_number")
context = {
**self.admin_site.each_context(request),
"title": "Subjects",
"subjects": subjects,
"opts": self.model._meta,
"has_add_permission": self.has_add_permission(request),
}
return TemplateResponse(request, "Hod/subject.html", context)
@admin.register(NewsEvent)
class NewsEventAdmin(admin.ModelAdmin):
list_display = ("title", "type", "created_at")
search_fields = ("title", "summary", "type")
list_filter = ("type", "created_at")
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path("", self.news_event_list_view, name="newsevent_changelist"),
]
return custom_urls + urls
def news_event_list_view(self, request):
news_events = NewsEvent.objects.all().order_by("-created_at")
context = {
**self.admin_site.each_context(request),
"title": "News and Events",
"news_events": news_events,
"opts": self.model._meta,
"has_add_permission": self.has_add_permission(request),
}
return TemplateResponse(request, "Hod/news_events.html", context)
@admin.register(Attendance)
class AttendanceAdmin(admin.ModelAdmin):
list_display = ("student", "subject", "date", "status")
search_fields = ("student__name", "subject__name", "status")
list_filter = ("status", "date", "subject")
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path("", self.attendance_list_view, name="attendance_changelist"),
]
return custom_urls + urls
def attendance_list_view(self, request):
attendance_records = Attendance.objects.select_related("student", "subject").all().order_by("-date")
context = {
**self.admin_site.each_context(request),
"title": "Attendance Records",
"attendance_records": attendance_records,
"opts": self.model._meta,
"has_add_permission": self.has_add_permission(request),
}
return TemplateResponse(request, "Hod/attendance.html", context)
# admin.site.register()
@admin.register(Library)
class LibraryAdmin(admin.ModelAdmin):
list_display = ("book_name", "category", "publication", "publication_year", "quantity", "available", "date_added")
search_fields = ("book_name", "category", "publication")
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path("", self.library_list_view, name="library_changelist"),
]
return custom_urls + urls
def library_list_view(self, request):
books = Library.objects.all().order_by("-date_added")
context = {
**self.admin_site.each_context(request),
"title": "Library",
"books": books,
"opts": self.model._meta,
"has_add_permission": self.has_add_permission(request),
}
return TemplateResponse(request, "Hod/library.html", context)
class SubjectMarkInline(admin.TabularInline):
model = SubjectMark
extra = 1
class SubjectMarkInline(admin.TabularInline):
model = SubjectMark
extra = 1 # Number of extra forms to display
fields = (
'subject',
'obtained_practical_marks',
'total_practical_marks',
'obtained_theory_marks',
'total_theory_marks',
'total_marks',
)
readonly_fields = ('total_marks',) # Make total_marks read-only
def save_related(self, request, formset, change):
super().save_related(request, formset, change)
for marksheet in formset.instance:
marksheet.save() # Ensure the Marksheet instance saves after each inline
@admin.register(Marksheet)
class MarksheetAdmin(admin.ModelAdmin):
inlines = [SubjectMarkInline]
list_display = ("student", "course", "total_marks", "obtained_marks", "grade")
list_filter = ("course", "grade")
search_fields = ("student__first_name", "student__last_name", "course__name")
def get_urls(self):
urls = super().get_urls()
custom_urls = [
path("", self.marksheet_list_view, name="marksheet_changelist"),
]
return custom_urls + urls
def marksheet_list_view(self, request):
marksheets = Marksheet.objects.select_related("student", "course").all()
context = {
**self.admin_site.each_context(request),
"title": "Marksheet List",
"marksheets": marksheets,
"opts": self.model._meta,
"has_add_permission": self.has_add_permission(request),
}
return TemplateResponse(request, "Hod/marksheet.html", context)
# @admin.register(Certificate)
# class CertificateAdmin(admin.ModelAdmin):
# list_display = ("title", "student", "course", "issued_date", "is_verified")
# search_fields = ("student__first_name", "student__last_name", "course__name", "title")
# list_filter = ("is_verified", "issued_date")
# # Optionally, you can add actions for verification or custom actions
# actions = ["mark_verified", "mark_unverified"]
# def mark_verified(self, request, queryset):
# queryset.update(is_verified=True)
# def mark_unverified(self, request, queryset):
# queryset.update(is_verified=False)
# mark_verified.short_description = "Mark selected certificates as verified"
# mark_unverified.short_description = "Mark selected certificates as unverified"
-6
View File
@@ -1,6 +0,0 @@
from django.apps import AppConfig
class AppConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "app"
-259
View File
@@ -1,259 +0,0 @@
# Generated by Django 5.1.4 on 2025-01-09 17:58
import django.core.validators
import django.db.models.deletion
from decimal import Decimal
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0012_alter_user_first_name_max_length'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='AcademicYear',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('year', models.CharField(max_length=255, unique=True)),
],
options={
'verbose_name': 'Academic Year',
'verbose_name_plural': 'Academic Years',
},
),
migrations.CreateModel(
name='Course',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100)),
('level', models.CharField(choices=[('basic', 'Basic'), ('primary', 'Primary'), ('secondary', 'Secondary'), ('vocational traning', 'Vocational Traning'), ('higher secondary', 'Higher Secondary'), ('graduation', 'Graduation'), ('post graduation', 'Post Graduation')], max_length=45)),
('course_type', models.CharField(choices=[('semester', 'Semester-based'), ('yearly', 'Yearly-based')], max_length=10)),
('duration', models.PositiveIntegerField()),
],
options={
'verbose_name': 'Course',
'verbose_name_plural': 'Courses',
},
),
migrations.CreateModel(
name='Library',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('category', models.CharField(max_length=255)),
('book_name', models.CharField(max_length=255)),
('description', models.CharField(max_length=255)),
('publication', models.CharField(max_length=255)),
('publication_year', models.PositiveIntegerField()),
('quantity', models.PositiveIntegerField()),
('available', models.CharField(choices=[('Y', 'Yes'), ('N', 'NO')], max_length=1)),
('date_added', models.DateField(auto_now_add=True)),
],
options={
'verbose_name': 'Library',
'verbose_name_plural': 'Library',
},
),
migrations.CreateModel(
name='NewsEvent',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255)),
('summary', models.TextField()),
('type', models.CharField(choices=[('news', 'News'), ('event', 'Event')], max_length=5)),
('created_at', models.DateTimeField(auto_now_add=True)),
],
options={
'verbose_name': 'News/Event',
'verbose_name_plural': 'News/Events',
},
),
migrations.CreateModel(
name='Staff',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('active_status', models.BooleanField(default=True)),
('first_name', models.CharField(max_length=255)),
('middle_name', models.CharField(blank=True, max_length=255, null=True)),
('last_name', models.CharField(max_length=255)),
('email', models.EmailField(max_length=255, unique=True)),
('phone', models.CharField(max_length=10, validators=[django.core.validators.RegexValidator('^\\d{10}$')])),
('username', models.CharField(blank=True, max_length=255, null=True, unique=True)),
('password', models.CharField(max_length=255)),
('gender', models.CharField(choices=[('M', 'Male'), ('F', 'Female')], max_length=1)),
('position', models.CharField(choices=[('lab Assistant', 'Lab Assistant'), ('librarian', 'Librarian'), ('accountant', 'Accountant'), ('guard', 'Guard'), ('driver', 'Driver'), ('helper', 'Helper'), ('cleaner', 'Cleaner')], max_length=255)),
('address', models.CharField(max_length=255)),
('marital_status', models.CharField(choices=[('married', 'Married'), ('widowed', 'Widowed'), ('separated', 'Separated'), ('divorced', 'Divorced'), ('single', 'Single')], max_length=10)),
('date_of_joining', models.DateField()),
('group', models.ManyToManyField(blank=True, to='auth.group')),
('user', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Staff',
'verbose_name_plural': 'Staff',
},
),
migrations.CreateModel(
name='Student',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('active_status', models.BooleanField(default=True)),
('first_name', models.CharField(max_length=255)),
('middle_name', models.CharField(blank=True, max_length=255, null=True)),
('last_name', models.CharField(max_length=255)),
('email', models.EmailField(max_length=255, unique=True)),
('phone', models.CharField(max_length=10, validators=[django.core.validators.RegexValidator('^\\d{10}$')])),
('username', models.CharField(blank=True, max_length=255, null=True, unique=True)),
('password', models.CharField(max_length=255)),
('date_of_birth', models.DateField()),
('gender', models.CharField(choices=[('M', 'Male'), ('F', 'Female')], max_length=1)),
('address', models.CharField(max_length=255)),
('father_name', models.CharField(max_length=100)),
('father_phone_no', models.CharField(max_length=10, validators=[django.core.validators.RegexValidator('^\\d{10}$')])),
('father_email', models.EmailField(blank=True, max_length=254, null=True)),
('father_occupation', models.CharField(choices=[('agriculture', 'Agriculture'), ('banker', 'Banker'), ('business', 'Business'), ('doctor', 'Doctor'), ('farmer', 'Farmer'), ('fisherman', 'Fisherman'), ('public service', 'Public Service'), ('private service', 'Private Service'), ('shopkeeper', 'Shopkeeper'), ('driver', 'Driver'), ('worker', 'Worker'), ('N/A', 'N/A')], default='N/A', max_length=45)),
('mother_name', models.CharField(max_length=100)),
('mother_phone_no', models.CharField(blank=True, max_length=10, null=True, validators=[django.core.validators.RegexValidator('^\\d{10}$')])),
('mother_email', models.EmailField(blank=True, max_length=254, null=True)),
('mother_occupation', models.CharField(choices=[('agriculture', 'Agriculture'), ('banker', 'Banker'), ('business', 'Business'), ('doctor', 'Doctor'), ('farmer', 'Farmer'), ('fisherman', 'Fisherman'), ('public service', 'Public Service'), ('private service', 'Private Service'), ('shopkeeper', 'Shopkeeper'), ('driver', 'Driver'), ('houseWife', 'HouseWife'), ('worker', 'Worker'), ('N/A', 'N/A')], default='N/A', max_length=45)),
('guardian_name', models.CharField(max_length=100)),
('guardian_phone_no', models.CharField(max_length=10, validators=[django.core.validators.RegexValidator('^\\d{10}$')])),
('guardian_email', models.EmailField(blank=True, max_length=254, null=True)),
('relationship_with_student', models.CharField(choices=[('father', 'Father'), ('mother', 'Mother'), ('brother', 'Brother'), ('sister', 'Sister'), ('uncle', 'Uncle'), ('aunt', 'Aunt'), ('grandfather', 'Grandfather')], max_length=45)),
('academic_year', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.academicyear')),
('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.course')),
('group', models.ManyToManyField(blank=True, to='auth.group')),
('user', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Student',
'verbose_name_plural': 'Students',
},
),
migrations.CreateModel(
name='Marksheet',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('total_marks', models.PositiveIntegerField(default=Decimal('0.00'), help_text='Total marks for the course', validators=[django.core.validators.MinValueValidator(1)])),
('obtained_marks', models.PositiveIntegerField(default=Decimal('0.00'), help_text='Total marks obtained by the student', validators=[django.core.validators.MinValueValidator(0)])),
('grade', models.CharField(blank=True, choices=[('A+', 'A+'), ('A', 'A'), ('B+', 'B+'), ('B', 'B'), ('C+', 'C+'), ('C', 'C'), ('D', 'D'), ('E', 'E')], help_text='Grade assigned based on marks', max_length=2, null=True)),
('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='marksheets', to='app.course')),
('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='marksheets', to='app.student')),
],
options={
'verbose_name': 'Marksheet',
'verbose_name_plural': 'Marksheets',
'unique_together': {('student', 'course')},
},
),
migrations.CreateModel(
name='Certificate',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('title', models.CharField(max_length=255)),
('description', models.TextField(blank=True, null=True)),
('issue_date', models.DateField(auto_now_add=True)),
('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.course')),
('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.student')),
],
options={
'verbose_name': 'Certificate',
'verbose_name_plural': 'Certificate',
},
),
migrations.CreateModel(
name='Subject',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
('semester_or_year_number', models.PositiveIntegerField()),
('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subjects', to='app.course')),
],
options={
'verbose_name': 'Subject',
'verbose_name_plural': 'Subjects',
},
),
migrations.CreateModel(
name='Result',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('practical_marks', models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=5)),
('exam_marks', models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=5)),
('total_marks', models.DecimalField(decimal_places=2, default=Decimal('0.00'), editable=False, max_digits=5)),
('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.student')),
('subject', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.subject')),
],
options={
'verbose_name': 'Result',
'verbose_name_plural': 'Results',
},
),
migrations.CreateModel(
name='Attendance',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('date', models.DateField()),
('status', models.CharField(choices=[('present', 'Present'), ('absent', 'Absent')], max_length=10)),
('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.student')),
('subject', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='app.subject')),
],
options={
'verbose_name': 'Attendance',
'verbose_name_plural': 'Attendance Records',
},
),
migrations.CreateModel(
name='Teacher',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('active_status', models.BooleanField(default=True)),
('first_name', models.CharField(max_length=255)),
('middle_name', models.CharField(blank=True, max_length=255, null=True)),
('last_name', models.CharField(max_length=255)),
('email', models.EmailField(max_length=255, unique=True)),
('phone', models.CharField(max_length=10, validators=[django.core.validators.RegexValidator('^\\d{10}$')])),
('username', models.CharField(blank=True, max_length=255, null=True, unique=True)),
('password', models.CharField(max_length=255)),
('address', models.CharField(max_length=255)),
('gender', models.CharField(choices=[('M', 'Male'), ('F', 'Female')], max_length=1)),
('qualification', models.CharField(choices=[('BA', 'BA'), ('BBS', 'BBS'), ('BE', 'BE'), ('BEd', 'BEd'), ('BSc', 'BSc'), ('MA', 'MA'), ('MSc', 'MSc'), ('MBS', 'MBS'), ('ME', 'ME'), ('PhD', 'PhD'), ('Others', 'Others')], max_length=45)),
('specialization', models.CharField(max_length=255)),
('marital_status', models.CharField(choices=[('married', 'Married'), ('widowed', 'Widowed'), ('separated', 'Separated'), ('divorced', 'Divorced'), ('single', 'Single')], max_length=10)),
('date_of_joining', models.DateField()),
('group', models.ManyToManyField(blank=True, to='auth.group')),
('user', models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'Teacher',
'verbose_name_plural': 'Teachers',
},
),
migrations.AddField(
model_name='subject',
name='teacher',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='subjects', to='app.teacher'),
),
migrations.CreateModel(
name='SubjectMark',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('obtained_practical_marks', models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=5)),
('total_practical_marks', models.DecimalField(decimal_places=2, default=Decimal('20.00'), max_digits=5)),
('obtained_theory_marks', models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=5)),
('total_theory_marks', models.DecimalField(decimal_places=2, default=Decimal('80.00'), max_digits=5)),
('total_marks', models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=5)),
('marksheet', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subject_marks', to='app.marksheet')),
('subject', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='subject_marks', to='app.subject')),
],
options={
'unique_together': {('marksheet', 'subject')},
},
),
]
@@ -1,44 +0,0 @@
# Generated by Django 5.1.4 on 2025-01-09 18:06
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='staff',
name='phone',
field=models.CharField(max_length=10, validators=[django.core.validators.RegexValidator('^\\+?1?\\d{9,15}$')]),
),
migrations.AlterField(
model_name='student',
name='father_phone_no',
field=models.CharField(max_length=10, validators=[django.core.validators.RegexValidator('^\\+?1?\\d{9,15}$')]),
),
migrations.AlterField(
model_name='student',
name='guardian_phone_no',
field=models.CharField(max_length=10, validators=[django.core.validators.RegexValidator('^\\+?1?\\d{9,15}$')]),
),
migrations.AlterField(
model_name='student',
name='mother_phone_no',
field=models.CharField(blank=True, max_length=10, null=True, validators=[django.core.validators.RegexValidator('^\\+?1?\\d{9,15}$')]),
),
migrations.AlterField(
model_name='student',
name='phone',
field=models.CharField(max_length=10, validators=[django.core.validators.RegexValidator('^\\+?1?\\d{9,15}$')]),
),
migrations.AlterField(
model_name='teacher',
name='phone',
field=models.CharField(max_length=10, validators=[django.core.validators.RegexValidator('^\\+?1?\\d{9,15}$')]),
),
]
@@ -1,53 +0,0 @@
# Generated by Django 5.1.4 on 2025-01-10 06:17
import django.db.models.deletion
import django.utils.timezone
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0002_alter_staff_phone_alter_student_father_phone_no_and_more'),
]
operations = [
migrations.AlterModelOptions(
name='certificate',
options={'verbose_name': 'Certificate', 'verbose_name_plural': 'Certificates'},
),
migrations.RemoveField(
model_name='certificate',
name='issue_date',
),
migrations.AddField(
model_name='certificate',
name='certificate_file',
field=models.FileField(blank=True, null=True, upload_to='certificates/'),
),
migrations.AddField(
model_name='certificate',
name='is_verified',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='certificate',
name='issued_date',
field=models.DateField(default=django.utils.timezone.now),
),
migrations.AlterField(
model_name='certificate',
name='course',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='certificates', to='app.course'),
),
migrations.AlterField(
model_name='certificate',
name='id',
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
),
migrations.AlterField(
model_name='certificate',
name='student',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='certificates', to='app.student'),
),
]
@@ -1,31 +0,0 @@
# Generated by Django 5.1.4 on 2025-01-10 06:21
import django.db.models.deletion
import django.utils.timezone
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0003_alter_certificate_options_and_more'),
]
operations = [
migrations.CreateModel(
name='CharacterCertificate',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('issued_date', models.DateField(default=django.utils.timezone.now)),
('issued_by', models.CharField(max_length=255)),
('remarks', models.TextField()),
('is_verified', models.BooleanField(default=False)),
('certificate_file', models.FileField(blank=True, null=True, upload_to='character_certificates/')),
('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='character_certificates', to='app.student')),
],
options={
'verbose_name': 'Character Certificate',
'verbose_name_plural': 'Character Certificates',
},
),
]
@@ -1,23 +0,0 @@
# Generated by Django 5.1.4 on 2025-01-10 06:22
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('app', '0004_charactercertificate'),
]
operations = [
migrations.RemoveField(
model_name='charactercertificate',
name='student',
),
migrations.DeleteModel(
name='Certificate',
),
migrations.DeleteModel(
name='CharacterCertificate',
),
]
@@ -1,30 +0,0 @@
# Generated by Django 5.1.4 on 2025-01-10 06:49
import django.core.validators
from decimal import Decimal
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0005_remove_charactercertificate_student_and_more'),
]
operations = [
migrations.AlterField(
model_name='marksheet',
name='grade',
field=models.CharField(blank=True, choices=[('A+', 'A+'), ('A', 'A'), ('B+', 'B+'), ('B', 'B'), ('C+', 'C+'), ('C', 'C'), ('D', 'D'), ('E', 'E')], max_length=2, null=True),
),
migrations.AlterField(
model_name='marksheet',
name='obtained_marks',
field=models.PositiveIntegerField(default=Decimal('0.00'), validators=[django.core.validators.MinValueValidator(0)]),
),
migrations.AlterField(
model_name='marksheet',
name='total_marks',
field=models.PositiveIntegerField(default=Decimal('0.00'), validators=[django.core.validators.MinValueValidator(1)]),
),
]
@@ -1,19 +0,0 @@
# Generated by Django 5.1.4 on 2025-01-10 06:50
from decimal import Decimal
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0006_alter_marksheet_grade_alter_marksheet_obtained_marks_and_more'),
]
operations = [
migrations.AlterField(
model_name='subjectmark',
name='total_marks',
field=models.DecimalField(blank=True, decimal_places=2, default=Decimal('0.00'), max_digits=5, null=True),
),
]
@@ -1,25 +0,0 @@
# Generated by Django 5.1.4 on 2025-01-10 06:51
import django.core.validators
from decimal import Decimal
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0007_alter_subjectmark_total_marks'),
]
operations = [
migrations.AlterField(
model_name='marksheet',
name='total_marks',
field=models.PositiveIntegerField(blank=True, default=Decimal('0.00'), null=True, validators=[django.core.validators.MinValueValidator(1)]),
),
migrations.AlterField(
model_name='subjectmark',
name='total_marks',
field=models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=5),
),
]
@@ -1,20 +0,0 @@
# Generated by Django 5.1.4 on 2025-01-10 06:52
import django.core.validators
from decimal import Decimal
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0008_alter_marksheet_total_marks_and_more'),
]
operations = [
migrations.AlterField(
model_name='marksheet',
name='total_marks',
field=models.PositiveIntegerField(blank=True, default=Decimal('0.00'), null=True, validators=[django.core.validators.MinValueValidator(0)]),
),
]
View File
Whitespace-only changes.
-450
View File
@@ -1,450 +0,0 @@
from django.db import models
from django.contrib.auth.models import User, Group
from django.core.validators import RegexValidator
from django.contrib.auth.hashers import make_password
import random
from decimal import Decimal
from datetime import time, timedelta, datetime
from django.core.validators import MinValueValidator, MaxValueValidator
from django.utils import timezone
# Abstract BaseUser Model
class BaseUser(models.Model):
active_status = models.BooleanField(default=True)
first_name = models.CharField(max_length=255)
middle_name = models.CharField(max_length=255, blank=True, null=True)
last_name = models.CharField(max_length=255)
email = models.EmailField(max_length=255, unique=True)
phone = models.CharField(
max_length=10, validators=[RegexValidator(r"^\+?1?\d{9,15}$")]
)
username = models.CharField(max_length=255, unique=True, blank=True, null=True)
password = models.CharField(max_length=255)
group = models.ManyToManyField(Group, blank=True)
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True)
class Meta:
abstract = True
def save(self, *args, **kwargs):
if not self.username:
self.username = f"{self.first_name.lower()}_{random.randint(1000, 9999)}"
if self._state.adding or not self.password.startswith("pbkdf2_"):
self.password = make_password(self.password)
if not self.user:
self.user = User.objects.create(
username=self.username,
email=self.email,
first_name=self.first_name,
last_name=self.last_name,
is_staff=True,
is_active=self.active_status,
password=self.password,
)
else:
self.user.username = self.username
self.user.email = self.email
self.user.first_name = self.first_name
self.user.last_name = self.last_name
self.user.is_active = self.active_status
self.user.is_staff = True
self.user.password = self.password
super().save(*args, **kwargs)
self.user.groups.set(self.group.all())
self.user.save()
def __str__(self):
return f"{self.first_name} {self.last_name}"
# Teacher model
class Teacher(BaseUser):
address = models.CharField(max_length=255)
gender = models.CharField(max_length=1, choices=[("M", "Male"), ("F", "Female")])
qualification_choice = (
("BA", "BA"),
("BBS", "BBS"),
("BE", "BE"),
("BEd", "BEd"),
("BSc", "BSc"),
("MA", "MA"),
("MSc", "MSc"),
("MBS", "MBS"),
("ME", "ME"),
("PhD", "PhD"),
("Others", "Others"),
)
qualification = models.CharField(choices=qualification_choice, max_length=45)
specialization = models.CharField(max_length=255)
marital_status_choice = (
("married", "Married"),
("widowed", "Widowed"),
("separated", "Separated"),
("divorced", "Divorced"),
("single", "Single"),
)
marital_status = models.CharField(choices=marital_status_choice, max_length=10)
date_of_joining = models.DateField()
class Meta:
verbose_name = "Teacher"
verbose_name_plural = "Teachers"
# Student model
class Student(BaseUser):
date_of_birth = models.DateField(blank=False)
gender = models.CharField(max_length=1, choices=[("M", "Male"), ("F", "Female")])
address = models.CharField(max_length=255)
course = models.ForeignKey("Course", on_delete=models.CASCADE)
academic_year = models.ForeignKey("AcademicYear", on_delete=models.CASCADE)
father_name = models.CharField(max_length=100)
father_phone_no = models.CharField(
max_length=10, validators=[RegexValidator(r"^\+?1?\d{9,15}$")]
)
father_email = models.EmailField(blank=True, null=True)
father_occupation_choice = (
("agriculture", "Agriculture"),
("banker", "Banker"),
("business", "Business"),
("doctor", "Doctor"),
("farmer", "Farmer"),
("fisherman", "Fisherman"),
("public service", "Public Service"),
("private service", "Private Service"),
("shopkeeper", "Shopkeeper"),
("driver", "Driver"),
("worker", "Worker"),
("N/A", "N/A"),
)
father_occupation = models.CharField(
choices=father_occupation_choice, max_length=45, default="N/A"
)
mother_name = models.CharField(max_length=100)
mother_phone_no = models.CharField(
max_length=10,
validators=[RegexValidator(r"^\+?1?\d{9,15}$")],
blank=True,
null=True,
)
mother_email = models.EmailField(blank=True, null=True)
mother_occupation_choice = (
("agriculture", "Agriculture"),
("banker", "Banker"),
("business", "Business"),
("doctor", "Doctor"),
("farmer", "Farmer"),
("fisherman", "Fisherman"),
("public service", "Public Service"),
("private service", "Private Service"),
("shopkeeper", "Shopkeeper"),
("driver", "Driver"),
("houseWife", "HouseWife"),
("worker", "Worker"),
("N/A", "N/A"),
)
mother_occupation = models.CharField(
choices=mother_occupation_choice, max_length=45, default="N/A"
)
guardian_name = models.CharField(max_length=100)
guardian_phone_no = models.CharField(
max_length=10, validators=[RegexValidator(r"^\+?1?\d{9,15}$")]
)
guardian_email = models.EmailField(blank=True, null=True)
relationship_choice = (
("father", "Father"),
("mother", "Mother"),
("brother", "Brother"),
("sister", "Sister"),
("uncle", "Uncle"),
("aunt", "Aunt"),
("grandfather", "Grandfather"),
)
relationship_with_student = models.CharField(
choices=relationship_choice, max_length=45
)
class Meta:
verbose_name = "Student"
verbose_name_plural = "Students"
# Staff model
class Staff(BaseUser):
gender = models.CharField(max_length=1, choices=[("M", "Male"), ("F", "Female")])
position = models.CharField(
max_length=255,
choices=[
("lab Assistant", "Lab Assistant"),
("librarian", "Librarian"),
("accountant", "Accountant"),
("guard", "Guard"),
("driver", "Driver"),
("helper", "Helper"),
("cleaner", "Cleaner"),
],
)
address = models.CharField(max_length=255)
marital_status_choice = (
("married", "Married"),
("widowed", "Widowed"),
("separated", "Separated"),
("divorced", "Divorced"),
("single", "Single"),
)
marital_status = models.CharField(choices=marital_status_choice, max_length=10)
date_of_joining = models.DateField()
class Meta:
verbose_name = "Staff"
verbose_name_plural = "Staff"
# Course model
class Course(models.Model):
name = models.CharField(max_length=100)
level_choice = (
("basic", "Basic"),
("primary", "Primary"),
("secondary", "Secondary"),
("vocational traning", "Vocational Traning"),
("higher secondary", "Higher Secondary"),
("graduation", "Graduation"),
("post graduation", "Post Graduation"),
)
level = models.CharField(choices=level_choice, max_length=45)
course_type = models.CharField(
max_length=10,
choices=[("semester", "Semester-based"), ("yearly", "Yearly-based")],
)
duration = models.PositiveIntegerField()
def __str__(self):
return self.name
class Meta:
verbose_name = "Course"
verbose_name_plural = "Courses"
# AcademicYear model
class AcademicYear(models.Model):
year = models.CharField(max_length=255, unique=True)
def __str__(self):
return self.year
class Meta:
verbose_name = "Academic Year"
verbose_name_plural = "Academic Years"
# Subject model
class Subject(models.Model):
name = models.CharField(max_length=255)
course = models.ForeignKey(
"Course", on_delete=models.CASCADE, related_name="subjects"
)
semester_or_year_number = models.PositiveIntegerField()
teacher = models.ForeignKey(
"Teacher",
on_delete=models.CASCADE,
related_name="subjects",
null=True,
blank=True,
)
def __str__(self):
return f"{self.name} (Sem/Year {self.semester_or_year_number})"
class Meta:
verbose_name = "Subject"
verbose_name_plural = "Subjects"
# NewsEvent model
class NewsEvent(models.Model):
class NewsEventType(models.TextChoices):
NEWS = "news", "News"
EVENT = "event", "Event"
title = models.CharField(max_length=255)
summary = models.TextField()
type = models.CharField(max_length=5, choices=NewsEventType.choices)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.title} ({self.type})"
class Meta:
verbose_name = "News/Event"
verbose_name_plural = "News/Events"
# Attendance model
class Attendance(models.Model):
id = models.AutoField(primary_key=True)
student = models.ForeignKey("Student", on_delete=models.CASCADE)
subject = models.ForeignKey("Subject", on_delete=models.CASCADE)
date = models.DateField()
status = models.CharField(
max_length=10, choices=[("present", "Present"), ("absent", "Absent")]
)
class Meta:
verbose_name = "Attendance"
verbose_name_plural = "Attendance Records"
# Result model
class Result(models.Model):
id = models.AutoField(primary_key=True)
student = models.ForeignKey("Student", on_delete=models.CASCADE)
subject = models.ForeignKey("Subject", on_delete=models.CASCADE)
practical_marks = models.DecimalField(
max_digits=5, decimal_places=2, default=Decimal("0.00")
)
exam_marks = models.DecimalField(
max_digits=5, decimal_places=2, default=Decimal("0.00")
)
total_marks = models.DecimalField(
max_digits=5, decimal_places=2, default=Decimal("0.00"), editable=False
)
def get_total(self):
return Decimal(str(self.practical_marks or 0)) + Decimal(
str(self.exam_marks or 0)
)
def save(self, *args, **kwargs):
self.total_marks = self.get_total()
super().save(*args, **kwargs)
def __str__(self):
return f"{self.student} - {self.subject} - Total: {self.total_marks}"
class Meta:
verbose_name = "Result"
verbose_name_plural = "Results"
class Library(models.Model):
category = models.CharField(max_length=255)
book_name = models.CharField(max_length=255)
description = models.CharField(max_length=255)
publication = models.CharField(max_length=255)
publication_year = models.PositiveIntegerField()
quantity = models.PositiveIntegerField()
available = models.CharField(max_length=1, choices=[("Y", "Yes"), ("N", "NO")])
date_added = models.DateField(auto_now_add=True)
def __str__(self):
return self.book_name
class Meta:
verbose_name = "Library"
verbose_name_plural = "Library"
# class Certificate(models.Model):
# title = models.CharField(max_length=255)
# student = models.ForeignKey("Student", on_delete=models.CASCADE, related_name="certificates")
# course = models.ForeignKey("Course", on_delete=models.CASCADE, related_name="certificates")
# issued_date = models.DateField(default=timezone.now)
# is_verified = models.BooleanField(default=False)
# certificate_file = models.FileField(upload_to="certificates/", blank=True, null=True)
# description = models.TextField(blank=True, null=True)
# def __str__(self):
# return f"{self.title} - {self.student.first_name} {self.student.last_name}"
# class Meta:
# verbose_name = "Certificate"
# verbose_name_plural = "Certificates"
class Marksheet(models.Model):
student = models.ForeignKey("Student", on_delete=models.CASCADE, related_name="marksheets")
course = models.ForeignKey("Course", on_delete=models.CASCADE, related_name="marksheets")
total_marks = models.PositiveIntegerField(validators=[MinValueValidator(0)], default=Decimal("0.00"), blank=True, null=True)
obtained_marks = models.PositiveIntegerField(validators=[MinValueValidator(0)], default=Decimal("0.00"))
grade = models.CharField(max_length=2, choices=[
("A+", "A+"),
("A", "A"),
("B+", "B+"),
("B", "B"),
("C+", "C+"),
("C", "C"),
("D", "D"),
("E", "E"),
], blank=True, null=True)
class Meta:
verbose_name = "Marksheet"
verbose_name_plural = "Marksheets"
unique_together = ("student", "course")
def calculate_totals(self):
subject_marks = self.subject_marks.all()
total_marks = sum(subject.total_practical_marks + subject.total_theory_marks for subject in subject_marks) or Decimal("0.00")
obtained_marks = sum(subject.obtained_practical_marks + subject.obtained_theory_marks for subject in subject_marks) or Decimal("0.00")
return total_marks, obtained_marks
def save(self, *args, **kwargs):
if not self.pk:
super().save(*args, **kwargs)
self.total_marks, self.obtained_marks = self.calculate_totals()
if self.total_marks > 0:
percentage = (self.obtained_marks / self.total_marks) * 100
if percentage >= 90:
self.grade = "A+"
elif percentage >= 80:
self.grade = "A"
elif percentage >= 70:
self.grade = "B+"
elif percentage >= 60:
self.grade = "B"
elif percentage >= 50:
self.grade = "C+"
elif percentage >= 40:
self.grade = "C"
elif percentage >= 30:
self.grade = "D"
else:
self.grade = "E"
super().save(*args, **kwargs)
def __str__(self):
return f"Marksheet: {self.student.first_name} {self.student.last_name}"
class SubjectMark(models.Model):
marksheet = models.ForeignKey(Marksheet, on_delete=models.CASCADE, related_name="subject_marks")
subject = models.ForeignKey("Subject", on_delete=models.CASCADE, related_name="subject_marks")
obtained_practical_marks = models.DecimalField(max_digits=5, decimal_places=2, default=Decimal("0.00"))
total_practical_marks = models.DecimalField(max_digits=5, decimal_places=2, default=Decimal("20.00"))
obtained_theory_marks = models.DecimalField(max_digits=5, decimal_places=2, default=Decimal("0.00"))
total_theory_marks = models.DecimalField(max_digits=5, decimal_places=2, default=Decimal("80.00"))
total_marks = models.DecimalField(max_digits=5, decimal_places=2, default=Decimal("0.00"))
def get_total(self):
return Decimal(str(self.obtained_practical_marks or 0)) + Decimal(str(self.obtained_theory_marks or 0))
def save(self, *args, **kwargs):
self.total_marks = self.get_total()
super().save(*args, **kwargs)
self.marksheet.save() # Trigger the marksheet save to recalculate totals
class Meta:
unique_together = ("marksheet", "subject")
def __str__(self):
return f"{self.subject.name} - {self.marksheet.student.first_name}"
-3
View File
@@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.
-12
View File
@@ -1,12 +0,0 @@
from django.urls import path
from app import views
urlpatterns = [
path("dashboard", views.dashboard, name="dashboard"),
path("studentdashboard", views.studentdashboard, name="studentdashboard"),
# path("marksheet", views.marksheet, name="marksheet"),
path('marksheet/<int:pk>/', views.view_marksheet, name='app_marksheet_view')
# path("course/manage", views.Add_Course, name="add_course"),
# path("course/edit/<int:id>", views.Edit_Course, name="edit_course"),
# path("course/delete/<int:id>", views.Delete_Course, name="delete_course"),
]
-150
View File
@@ -1,150 +0,0 @@
from django.shortcuts import render, redirect, get_object_or_404
from django.views.generic import DetailView
from django.contrib.admin import site
from app.models import (
Student,
NewsEvent,
AcademicYear,
Subject,
Teacher,
Staff,
Course,
Marksheet,
SubjectMark,
)
from django.contrib.auth.decorators import login_required
from django.contrib import messages
def view_marksheet(request, pk):
try:
marksheet = Marksheet.objects.get(pk=pk)
percentage = (
(marksheet.obtained_marks / marksheet.total_marks) * 100
if marksheet.total_marks > 0
else 0
)
context = {
"marksheet": marksheet,
"percentage": percentage,
"student": marksheet.student,
"school_name": "XYZ Secondary School",
"theory_max": 80,
"practical_max": 20,
"exam_year": marksheet.student.academic_year,
}
return render(request, "Hod/view_marksheet.html", context)
except Marksheet.DoesNotExist:
return HttpResponse("Marksheet not found", status=404)
@login_required
def Add_Course(request):
courses = Course.objects.all()
context = {
**site.each_context(request), # This adds admin context
"title": "Manage Courses",
"courses": courses,
"subtitle": "Course Management",
"site_title": "School Management",
"has_permission": True,
"is_popup": False,
"is_nav_sidebar_enabled": True,
"available_apps": site.get_app_list(request),
}
if request.method == "POST":
name = request.POST.get("name")
level = request.POST.get("level")
course_type = request.POST.get("course_type")
duration = request.POST.get("duration")
Course.objects.create(
name=name, level=level, course_type=course_type, duration=duration
)
messages.success(request, "Course Added Successfully!")
return redirect("add_course")
return render(request, "Hod/add_course.html", context)
@login_required
def Edit_Course(request, id):
course = Course.objects.all()
if request.method == "POST":
name = request.POST.get("name")
Course.objects.filter(id=id).update(
name=name,
)
messages.success(request, "Course Updated Successfully!")
return redirect("add_course")
context = {
"course": course,
}
return render(request, "Hod/add_course.html", context)
@login_required
def Delete_Course(request, id):
Course.objects.filter(id=id).delete()
messages.success(request, "Course Deleted Successfully")
return redirect("add_course")
@login_required
def dashboard(request):
if not request.user.is_superuser:
return redirect("studentdashboard")
total_student = Student.objects.count()
total_teacher = Teacher.objects.count()
total_staff = Staff.objects.count()
total_course = Course.objects.count()
total_subjects = Subject.objects.count()
context = {
**site.each_context(request),
"title": "Dashboard",
# "breadcrumbs": [{"name": "Dashboard", "url": "dashboard"}],
"total_student": total_student,
"total_teacher": total_teacher,
"total_staff": total_staff,
"total_course": total_course,
"total_subjects": total_subjects,
}
return render(request, "dashboard.html", context)
@login_required
def studentdashboard(request):
total_subject = Subject.objects.count()
student = Student.objects.get(user=request.user)
course_name = student.course.name
course = student.course
total_subjects = Subject.objects.filter(course=course).count()
subject = Subject.objects.filter(course=course)
context = {
**site.each_context(request),
"title": "Student Dashboard",
"total_subject": total_subject,
"course_name": course_name,
"subject": subject,
"total_subjects": total_subjects,
}
return render(request, "studentdashboard.html", context)
def marksheet(request):
marksheet = Marksheet.objects.first()
subject = SubjectMark.objects.filter(marksheet=marksheet)
context = {
**site.each_context(request),
"title": "Marksheet",
"marksheet": marksheet,
"subject": subject,
}
return render(request, "marksheet.html", context)