update
This commit is contained in:
1 parent
708246f41b
commit
8b268708b4
22 files changed
+609
-14
No files matched your search
+48
-4
@@ -1,16 +1,39 @@
|
||||
from django.contrib import admin
|
||||
from app.models import Teacher, Student, Staff, Course, AcademicYear, Subject, NewsEvent
|
||||
from app.models import (
|
||||
Teacher,
|
||||
Student,
|
||||
Staff,
|
||||
Course,
|
||||
AcademicYear,
|
||||
Subject,
|
||||
NewsEvent,
|
||||
Attendance,
|
||||
Result,
|
||||
)
|
||||
|
||||
|
||||
class BaseUserAdmin(admin.ModelAdmin):
|
||||
exclude = ["user"]
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
# Save the BaseUser instance
|
||||
super().save_model(request, obj, form, change)
|
||||
|
||||
# Sync the groups with the related User object
|
||||
if obj.user:
|
||||
obj.user.groups.set(obj.group.all()) # Sync groups
|
||||
obj.user.save() # Save the User object to persist changes
|
||||
|
||||
|
||||
@admin.register(Teacher)
|
||||
class TeacherAdmin(admin.ModelAdmin):
|
||||
class TeacherAdmin(BaseUserAdmin):
|
||||
list_display = ("id", "first_name", "last_name", "email", "phone", "active_status")
|
||||
search_fields = ("first_name", "last_name", "email", "phone")
|
||||
list_filter = ("active_status", "gender", "group")
|
||||
|
||||
|
||||
@admin.register(Student)
|
||||
class StudentAdmin(admin.ModelAdmin):
|
||||
class StudentAdmin(BaseUserAdmin):
|
||||
list_display = (
|
||||
"id",
|
||||
"first_name",
|
||||
@@ -26,7 +49,7 @@ class StudentAdmin(admin.ModelAdmin):
|
||||
|
||||
|
||||
@admin.register(Staff)
|
||||
class StaffAdmin(admin.ModelAdmin):
|
||||
class StaffAdmin(BaseUserAdmin):
|
||||
list_display = (
|
||||
"id",
|
||||
"first_name",
|
||||
@@ -65,3 +88,24 @@ class NewsEventAdmin(admin.ModelAdmin):
|
||||
list_display = ("id", "title", "type", "created_at")
|
||||
search_fields = ("title", "summary")
|
||||
list_filter = ("type", "created_at")
|
||||
|
||||
|
||||
@admin.register(Attendance)
|
||||
class AttendanceAdmin(admin.ModelAdmin):
|
||||
list_display = ("id", "student", "subject", "date", "status")
|
||||
|
||||
|
||||
@admin.register(Result)
|
||||
class ResultAdmin(admin.ModelAdmin):
|
||||
list_display = (
|
||||
"student",
|
||||
"subject",
|
||||
"practical_marks",
|
||||
"exam_marks",
|
||||
"total_marks",
|
||||
)
|
||||
readonly_fields = ("total_marks",)
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
obj.total_marks = obj.get_total()
|
||||
super().save_model(request, obj, form, change)
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class MainConfig(AppConfig):
|
||||
default_auto_field = "django.db.models.BigAutoField"
|
||||
name = "app"
|
||||
class AppConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'app'
|
||||
@@ -1,4 +1,4 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-06 16:53
|
||||
# Generated by Django 5.1.4 on 2025-01-06 17:31
|
||||
|
||||
import django.core.validators
|
||||
import django.db.models.deletion
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 04:39
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0001_initial'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='staff',
|
||||
name='user',
|
||||
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='student',
|
||||
name='user',
|
||||
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='teacher',
|
||||
name='user',
|
||||
field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,31 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 04:57
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0002_staff_user_student_user_teacher_user'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='staff',
|
||||
name='user',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='student',
|
||||
name='user',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='teacher',
|
||||
name='user',
|
||||
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,25 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 04:59
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0003_alter_staff_user_alter_student_user_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='staff',
|
||||
name='user',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='student',
|
||||
name='user',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='teacher',
|
||||
name='user',
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,31 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 05:01
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0004_remove_staff_user_remove_student_user_and_more'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='staff',
|
||||
name='user',
|
||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='student',
|
||||
name='user',
|
||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='teacher',
|
||||
name='user',
|
||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,25 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 05:10
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0005_staff_user_student_user_teacher_user'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='staff',
|
||||
name='user',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='student',
|
||||
name='user',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='teacher',
|
||||
name='user',
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,31 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 05:11
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0006_remove_staff_user_remove_student_user_and_more'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='staff',
|
||||
name='user',
|
||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='student',
|
||||
name='user',
|
||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='teacher',
|
||||
name='user',
|
||||
field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 06:43
|
||||
|
||||
import django.core.validators
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0007_staff_user_student_user_teacher_user'),
|
||||
]
|
||||
|
||||
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='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}$')]),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,24 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 06:45
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0008_alter_staff_phone_alter_student_phone_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
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')),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,25 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 09:41
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0009_attendance'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Result',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('practical_marks', models.IntegerField()),
|
||||
('exam_marks', models.IntegerField()),
|
||||
('total_marks', models.IntegerField(editable=False)),
|
||||
('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')),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 09:46
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0010_result'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='result',
|
||||
name='total_marks',
|
||||
field=models.IntegerField(),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,17 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 09:54
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0011_alter_result_total_marks'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='result',
|
||||
name='total_marks',
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 09:56
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0012_remove_result_total_marks'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='result',
|
||||
name='total_marks',
|
||||
field=models.IntegerField(default=0),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 10:00
|
||||
|
||||
from decimal import Decimal
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0013_result_total_marks'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='result',
|
||||
name='exam_marks',
|
||||
field=models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=5),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='result',
|
||||
name='practical_marks',
|
||||
field=models.DecimalField(decimal_places=2, default=Decimal('0.00'), max_digits=5),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='result',
|
||||
name='total_marks',
|
||||
field=models.DecimalField(decimal_places=2, default=Decimal('0.00'), editable=False, max_digits=5),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,30 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 10:14
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0014_alter_result_exam_marks_alter_result_practical_marks_and_more'),
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='staff',
|
||||
name='group',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='auth.group'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='student',
|
||||
name='group',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='auth.group'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='teacher',
|
||||
name='group',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='auth.group'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,41 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 10:18
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0015_alter_staff_group_alter_student_group_and_more'),
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='staff',
|
||||
name='group',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='student',
|
||||
name='group',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='teacher',
|
||||
name='group',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='staff',
|
||||
name='group',
|
||||
field=models.ManyToManyField(blank=True, null=True, to='auth.group'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='student',
|
||||
name='group',
|
||||
field=models.ManyToManyField(blank=True, null=True, to='auth.group'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='teacher',
|
||||
name='group',
|
||||
field=models.ManyToManyField(blank=True, null=True, to='auth.group'),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,29 @@
|
||||
# Generated by Django 5.1.4 on 2025-01-07 10:19
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('app', '0016_remove_staff_group_remove_student_group_and_more'),
|
||||
('auth', '0012_alter_user_first_name_max_length'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='staff',
|
||||
name='group',
|
||||
field=models.ManyToManyField(blank=True, to='auth.group'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='student',
|
||||
name='group',
|
||||
field=models.ManyToManyField(blank=True, to='auth.group'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='teacher',
|
||||
name='group',
|
||||
field=models.ManyToManyField(blank=True, to='auth.group'),
|
||||
),
|
||||
]
|
||||
+88
-4
@@ -1,47 +1,84 @@
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import Group
|
||||
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
|
||||
|
||||
|
||||
# Abstract BaseUser Model
|
||||
class BaseUser(models.Model):
|
||||
first_name = models.CharField(max_length=255)
|
||||
last_name = models.CharField(max_length=255)
|
||||
email = models.EmailField(max_length=255, unique=True)
|
||||
phone = models.CharField(
|
||||
max_length=15, validators=[RegexValidator(r"^\+?1?\d{9,15}$")]
|
||||
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)
|
||||
active_status = models.BooleanField(default=True)
|
||||
group = models.ForeignKey(Group, on_delete=models.SET_NULL, null=True, blank=True)
|
||||
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):
|
||||
# Generate a username if not provided
|
||||
if not self.username:
|
||||
self.username = f"{self.first_name.lower()}_{random.randint(1000, 9999)}"
|
||||
|
||||
# Hash the password if new or not already hashed
|
||||
if self._state.adding or not self.password.startswith("pbkdf2_"):
|
||||
self.password = make_password(self.password)
|
||||
|
||||
# Create or update the linked User object
|
||||
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
|
||||
|
||||
# Save the BaseUser instance
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
# Update the user's groups
|
||||
self.user.groups.set(self.group.all())
|
||||
|
||||
# Save the user object
|
||||
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")])
|
||||
|
||||
|
||||
# Student model
|
||||
class Student(BaseUser):
|
||||
gender = models.CharField(max_length=1, choices=[("M", "Male"), ("F", "Female")])
|
||||
course = models.ForeignKey("Course", on_delete=models.CASCADE)
|
||||
academic_year = models.ForeignKey("AcademicYear", on_delete=models.CASCADE)
|
||||
|
||||
|
||||
# Staff model
|
||||
class Staff(BaseUser):
|
||||
position = models.CharField(
|
||||
max_length=255,
|
||||
@@ -50,6 +87,7 @@ class Staff(BaseUser):
|
||||
address = models.CharField(max_length=255)
|
||||
|
||||
|
||||
# Course model
|
||||
class Course(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
course_type = models.CharField(
|
||||
@@ -62,13 +100,15 @@ class Course(models.Model):
|
||||
return self.name
|
||||
|
||||
|
||||
# AcademicYear model
|
||||
class AcademicYear(models.Model):
|
||||
batch = models.CharField(max_length=255, unique=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"Batch {self.batch}"
|
||||
return self.batch
|
||||
|
||||
|
||||
# Subject model
|
||||
class Subject(models.Model):
|
||||
name = models.CharField(max_length=255)
|
||||
course = models.ForeignKey(
|
||||
@@ -80,6 +120,7 @@ class Subject(models.Model):
|
||||
return f"{self.name} (Sem/Year {self.semester_or_year_number})"
|
||||
|
||||
|
||||
# NewsEvent model
|
||||
class NewsEvent(models.Model):
|
||||
title = models.CharField(max_length=255)
|
||||
summary = models.TextField()
|
||||
@@ -90,3 +131,46 @@ class NewsEvent(models.Model):
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.title} ({self.get_type_display()})"
|
||||
|
||||
|
||||
# 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")]
|
||||
)
|
||||
|
||||
|
||||
# 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 clean(self):
|
||||
self.total_marks = self.get_total()
|
||||
super().clean()
|
||||
|
||||
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}"
|
||||
@@ -0,0 +1,7 @@
|
||||
from django.urls import path
|
||||
from app import views
|
||||
|
||||
urlpatterns = [
|
||||
path("dashboard", views.dashboard, name="dashboard"),
|
||||
path("studentdashboard", views.studentdashboard, name="studentdashboard"),
|
||||
]
|
||||
+28
-2
@@ -1,3 +1,29 @@
|
||||
from django.shortcuts import render
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
from django.contrib.admin import site
|
||||
from app.models import Student, NewsEvent, Subject
|
||||
|
||||
# Create your views here.
|
||||
|
||||
# Dashboard for admin
|
||||
def dashboard(request):
|
||||
context = {
|
||||
**site.each_context(request),
|
||||
"title": "Dashboard",
|
||||
# "breadcrumbs": [{"name": "Dashboard", "url": "dashboard"}],
|
||||
}
|
||||
return render(request, "dashboard.html", context)
|
||||
|
||||
|
||||
# Student-specific dashboard
|
||||
def studentdashboard(request):
|
||||
context = {
|
||||
**site.each_context(request),
|
||||
"title": "Student Dashboard",
|
||||
}
|
||||
|
||||
if request.user.is_authenticated:
|
||||
news_events = NewsEvent.objects.all()
|
||||
subjects = Subject.objects.all()
|
||||
context["news_events"] = news_events
|
||||
context["subjects"] = subjects
|
||||
|
||||
return render(request, "studentdashboard.html", context)
|
||||
Reference in new issue
Block a user