signals(fix): huge errors
This commit is contained in:
1 parent
338e6db93b
commit
88f5416503
2 files changed
+303
-170
No files matched your search
@@ -14,6 +14,8 @@ from app.models import (
|
|||||||
CourseTracking, TeacherParentMeeting, SubjectFile
|
CourseTracking, TeacherParentMeeting, SubjectFile
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fake = Faker()
|
||||||
|
|
||||||
# Nepali-specific data
|
# Nepali-specific data
|
||||||
NEPALI_FIRST_NAMES = [
|
NEPALI_FIRST_NAMES = [
|
||||||
'Aarav', 'Aayush', 'Abhishek', 'Aditya', 'Amit', 'Anish', 'Anup', 'Arjun', 'Ashish', 'Bibek',
|
'Aarav', 'Aayush', 'Abhishek', 'Aditya', 'Amit', 'Anish', 'Anup', 'Arjun', 'Ashish', 'Bibek',
|
||||||
@@ -70,6 +72,8 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
# Get or create groups
|
# Get or create groups
|
||||||
staff_group, _ = Group.objects.get_or_create(name='Teacher')
|
staff_group, _ = Group.objects.get_or_create(name='Teacher')
|
||||||
|
hod_group, _ = Group.objects.get_or_create(name='HOD')
|
||||||
|
admission_officer_group, _ = Group.objects.get_or_create(name='Admission Officer')
|
||||||
parent_group, _ = Group.objects.get_or_create(name='Parent')
|
parent_group, _ = Group.objects.get_or_create(name='Parent')
|
||||||
student_group, _ = Group.objects.get_or_create(name='Student')
|
student_group, _ = Group.objects.get_or_create(name='Student')
|
||||||
|
|
||||||
@@ -121,7 +125,7 @@ class Command(BaseCommand):
|
|||||||
subjects = self._create_subjects(fake, courses, subjects_per_course)
|
subjects = self._create_subjects(fake, courses, subjects_per_course)
|
||||||
|
|
||||||
# Create staff members
|
# Create staff members
|
||||||
staff_members = self._create_staff(fake, num_staff, staff_group)
|
staff_members = self._create_staff(fake, num_staff, staff_group, courses)
|
||||||
|
|
||||||
# Create students
|
# Create students
|
||||||
students = self._create_students(fake, num_students, courses, batches, student_group)
|
students = self._create_students(fake, num_students, courses, batches, student_group)
|
||||||
@@ -159,7 +163,24 @@ class Command(BaseCommand):
|
|||||||
return f"{random.choice(NEPALI_FIRST_NAMES)} {random.choice(NEPALI_LAST_NAMES)}"
|
return f"{random.choice(NEPALI_FIRST_NAMES)} {random.choice(NEPALI_LAST_NAMES)}"
|
||||||
|
|
||||||
def _get_nepali_phone(self):
|
def _get_nepali_phone(self):
|
||||||
return f"98{random.randint(1000000, 9999999)}"
|
"""Generate a realistic Nepali phone number with proper formatting"""
|
||||||
|
# Nepal mobile prefixes (2 digits)
|
||||||
|
prefixes = ['98', '97']
|
||||||
|
|
||||||
|
# Generate a unique phone number
|
||||||
|
while True:
|
||||||
|
prefix = random.choice(prefixes)
|
||||||
|
# Generate 8 digits after the prefix (no spaces, no formatting)
|
||||||
|
digits = ''.join([str(random.randint(0, 9)) for _ in range(8)])
|
||||||
|
phone = f"{prefix}{digits}"
|
||||||
|
|
||||||
|
# Check if this phone already exists in any user model
|
||||||
|
student_exists = Student.objects.filter(phone=phone).exists()
|
||||||
|
staff_exists = Staff.objects.filter(phone=phone).exists()
|
||||||
|
parent_exists = Parent.objects.filter(phone=phone).exists()
|
||||||
|
|
||||||
|
if not (student_exists or staff_exists or parent_exists):
|
||||||
|
return phone
|
||||||
|
|
||||||
def _get_nepali_address(self, city):
|
def _get_nepali_address(self, city):
|
||||||
wards = [f"Ward No. {random.randint(1, 35)}" for _ in range(3)]
|
wards = [f"Ward No. {random.randint(1, 35)}" for _ in range(3)]
|
||||||
@@ -233,7 +254,7 @@ class Command(BaseCommand):
|
|||||||
return courses
|
return courses
|
||||||
|
|
||||||
def _create_subjects(self, fake, courses, subjects_per_course):
|
def _create_subjects(self, fake, courses, subjects_per_course):
|
||||||
subjects = []
|
subjects = [] # Initialize subjects list
|
||||||
|
|
||||||
subject_names = {
|
subject_names = {
|
||||||
'Computer Science Engineering': [
|
'Computer Science Engineering': [
|
||||||
@@ -285,7 +306,7 @@ class Command(BaseCommand):
|
|||||||
for year_or_sem in range(1, max_year_or_sem + 1):
|
for year_or_sem in range(1, max_year_or_sem + 1):
|
||||||
# Calculate number of subjects for this year/semester
|
# Calculate number of subjects for this year/semester
|
||||||
# Ensure at least 2 subjects per year/semester
|
# Ensure at least 2 subjects per year/semester
|
||||||
num_subjects = max(2, min(subjects_per_course, len(course_subjects)))
|
num_subjects = max(2, min(subjects_per_course, len(course_subject_names)))
|
||||||
|
|
||||||
# Select subjects ensuring no duplicates within the same year/semester
|
# Select subjects ensuring no duplicates within the same year/semester
|
||||||
available_subjects = [s for s in course_subject_names if not Subject.objects.filter(
|
available_subjects = [s for s in course_subject_names if not Subject.objects.filter(
|
||||||
@@ -319,36 +340,72 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
return subjects
|
return subjects
|
||||||
|
|
||||||
def _create_staff(self, fake, num_staff, staff_group):
|
def _create_staff(self, fake, num_staff, staff_group, courses):
|
||||||
staff_members = []
|
staff_members = []
|
||||||
|
# Keep track of which courses already have an HOD
|
||||||
|
courses_with_hod = set()
|
||||||
|
|
||||||
for i in range(num_staff):
|
for i in range(num_staff):
|
||||||
gender = random.choice(['Male', 'Female'])
|
try:
|
||||||
name = self._get_nepali_name()
|
gender = random.choice(['Male', 'Female'])
|
||||||
phone = self._get_nepali_phone()
|
name = self._get_nepali_name()
|
||||||
city = random.choice(NEPALI_CITIES)
|
phone = self._get_nepali_phone()
|
||||||
|
city = random.choice(NEPALI_CITIES)
|
||||||
staff = Staff(
|
designation = random.choice(NEPALI_DESIGNATIONS)
|
||||||
name=name,
|
|
||||||
phone=phone,
|
staff = Staff(
|
||||||
designation=random.choice(NEPALI_DESIGNATIONS),
|
name=name,
|
||||||
gender=gender,
|
phone=phone,
|
||||||
birth_date=fake.date_of_birth(minimum_age=30, maximum_age=65),
|
designation=designation,
|
||||||
email=fake.email(),
|
gender=gender,
|
||||||
temporary_address=self._get_nepali_address(city),
|
birth_date=fake.date_of_birth(minimum_age=30, maximum_age=65),
|
||||||
permanent_address=self._get_nepali_address(city),
|
email=fake.email(),
|
||||||
marital_status=random.choice(['Married', 'Unmarried']),
|
temporary_address=self._get_nepali_address(city),
|
||||||
parent_name=self._get_nepali_name(),
|
permanent_address=self._get_nepali_address(city),
|
||||||
parent_phone=self._get_nepali_phone(),
|
marital_status=random.choice(['Married', 'Unmarried']),
|
||||||
citizenship_no=f"{random.randint(10000, 99999)}-{random.randint(10000, 99999)}",
|
parent_name=self._get_nepali_name(),
|
||||||
joining_date=fake.date_between(start_date='-5y', end_date='today')
|
parent_phone=self._get_nepali_phone(),
|
||||||
)
|
citizenship_no=f"{random.randint(10000, 99999)}-{random.randint(10000, 99999)}",
|
||||||
staff.save()
|
joining_date=fake.date_between(start_date='-5y', end_date='today')
|
||||||
staff.set_password('staff123')
|
)
|
||||||
staff.save()
|
|
||||||
staff.groups.add(staff_group)
|
# First save to get a primary key
|
||||||
staff_members.append(staff)
|
staff.save()
|
||||||
self.stdout.write(self.style.SUCCESS(f'Created staff: {staff.name}'))
|
|
||||||
|
# Set appropriate password based on designation
|
||||||
|
password = 'staff123'
|
||||||
|
if staff.designation == 'HOD':
|
||||||
|
password = 'hod1234'
|
||||||
|
elif staff.designation == 'Admission Officer':
|
||||||
|
password = 'admissionofficer123'
|
||||||
|
|
||||||
|
staff.set_password(password)
|
||||||
|
|
||||||
|
# Add staff to the appropriate group based on designation
|
||||||
|
if staff.designation == 'HOD':
|
||||||
|
hod_group = Group.objects.get(name='HOD')
|
||||||
|
staff.groups.add(hod_group)
|
||||||
|
|
||||||
|
# Assign a course to HOD that doesn't already have one
|
||||||
|
available_courses = [c for c in courses if c.id not in courses_with_hod]
|
||||||
|
if available_courses:
|
||||||
|
course = random.choice(available_courses)
|
||||||
|
staff.course = course
|
||||||
|
courses_with_hod.add(course.id)
|
||||||
|
staff.save()
|
||||||
|
self.stdout.write(self.style.SUCCESS(f'Assigned HOD {staff.name} to course: {course.name}'))
|
||||||
|
|
||||||
|
elif staff.designation == 'Admission Officer':
|
||||||
|
admission_officer_group = Group.objects.get(name='Admission Officer')
|
||||||
|
staff.groups.add(admission_officer_group)
|
||||||
|
else:
|
||||||
|
staff.groups.add(staff_group)
|
||||||
|
|
||||||
|
staff_members.append(staff)
|
||||||
|
self.stdout.write(self.style.SUCCESS(f'Created staff: {staff.name} with phone {phone} (password: {password})'))
|
||||||
|
except Exception as e:
|
||||||
|
self.stdout.write(self.style.ERROR(f'Error creating staff: {str(e)}'))
|
||||||
|
continue
|
||||||
|
|
||||||
return staff_members
|
return staff_members
|
||||||
|
|
||||||
@@ -356,45 +413,61 @@ class Command(BaseCommand):
|
|||||||
students = []
|
students = []
|
||||||
|
|
||||||
for i in range(num_students):
|
for i in range(num_students):
|
||||||
gender = random.choice(['Male', 'Female'])
|
try:
|
||||||
name = self._get_nepali_name()
|
# Generate random personal information
|
||||||
phone = self._get_nepali_phone()
|
name = self._get_nepali_name()
|
||||||
city = random.choice(NEPALI_CITIES)
|
email = fake.email()
|
||||||
|
phone = self._get_nepali_phone()
|
||||||
course = random.choice(courses)
|
city = random.choice(NEPALI_CITIES)
|
||||||
max_semester = course.duration
|
temp_address = self._get_nepali_address(city)
|
||||||
if course.duration_type == 'Semester':
|
perm_address = self._get_nepali_address(city)
|
||||||
max_semester = course.duration * 2
|
birth_date = fake.date_of_birth(minimum_age=18, maximum_age=25)
|
||||||
|
|
||||||
current_period = random.randint(1, max_semester)
|
# Generate random academic information
|
||||||
|
course = random.choice(courses)
|
||||||
student = Student(
|
batch = random.choice(batches)
|
||||||
name=name,
|
current_period = random.randint(1, course.duration)
|
||||||
status=random.choice(['Active', 'Leave', 'Completed']),
|
if course.duration_type == 'Semester':
|
||||||
gender=gender,
|
current_period = random.randint(1, course.duration * 2)
|
||||||
birth_date=fake.date_of_birth(minimum_age=18, maximum_age=25),
|
|
||||||
email=fake.email(),
|
# Generate random joining date (within last 2 years)
|
||||||
phone=phone,
|
joining_date = datetime.now().date() - timedelta(days=random.randint(0, 730))
|
||||||
temporary_address=self._get_nepali_address(city),
|
|
||||||
permanent_address=self._get_nepali_address(city),
|
# Create student
|
||||||
marital_status=random.choice(['Married', 'Unmarried']),
|
student = Student(
|
||||||
parent_name=self._get_nepali_name(),
|
name=name,
|
||||||
parent_phone=self._get_nepali_phone(),
|
email=email,
|
||||||
citizenship_no=f"{random.randint(10000, 99999)}-{random.randint(10000, 99999)}",
|
phone=phone,
|
||||||
course=course,
|
temporary_address=temp_address,
|
||||||
current_period=current_period,
|
permanent_address=perm_address,
|
||||||
joining_date=fake.date_between(start_date='-4y', end_date='-1y')
|
birth_date=birth_date,
|
||||||
)
|
course=course,
|
||||||
student.save()
|
current_period=current_period,
|
||||||
student.set_password('student123')
|
joining_date=joining_date,
|
||||||
student.save()
|
gender=random.choice(['Male', 'Female', 'Other']),
|
||||||
student.groups.add(student_group)
|
status='Active',
|
||||||
|
is_active=True
|
||||||
batch = random.choice(batches)
|
)
|
||||||
student.batches.add(batch)
|
|
||||||
|
# Save the student first to get a primary key
|
||||||
students.append(student)
|
student.save()
|
||||||
self.stdout.write(self.style.SUCCESS(f'Created student: {student.name}'))
|
|
||||||
|
# Set password and save again
|
||||||
|
password = 'student123'
|
||||||
|
student.set_password(password)
|
||||||
|
|
||||||
|
# Add student to batch
|
||||||
|
batch.students.add(student)
|
||||||
|
|
||||||
|
# Add to student group
|
||||||
|
student.groups.add(student_group)
|
||||||
|
|
||||||
|
students.append(student)
|
||||||
|
self.stdout.write(self.style.SUCCESS(f'Created student {student.name} with phone {phone} (password: {password})'))
|
||||||
|
except Exception as e:
|
||||||
|
# Log the error but continue with other students
|
||||||
|
self.stdout.write(self.style.ERROR(f'Error creating student: {str(e)}'))
|
||||||
|
continue # Continue with next student
|
||||||
|
|
||||||
return students
|
return students
|
||||||
|
|
||||||
@@ -402,28 +475,44 @@ class Command(BaseCommand):
|
|||||||
parents = []
|
parents = []
|
||||||
|
|
||||||
for i in range(num_parents):
|
for i in range(num_parents):
|
||||||
name = self._get_nepali_name()
|
try:
|
||||||
phone = self._get_nepali_phone()
|
name = self._get_nepali_name()
|
||||||
city = random.choice(NEPALI_CITIES)
|
phone = self._get_nepali_phone()
|
||||||
|
city = random.choice(NEPALI_CITIES)
|
||||||
parent = Parent(
|
|
||||||
name=name,
|
parent = Parent(
|
||||||
phone=phone,
|
name=name,
|
||||||
email=fake.email(),
|
phone=phone,
|
||||||
address=self._get_nepali_address(city),
|
email=fake.email(),
|
||||||
)
|
address=self._get_nepali_address(city),
|
||||||
parent.save()
|
)
|
||||||
parent.set_password('parent123')
|
|
||||||
parent.save()
|
# First save to get a primary key
|
||||||
parent.groups.add(parent_group)
|
parent.save()
|
||||||
|
|
||||||
num_children = random.randint(1, min(2, len(students)))
|
# Set password directly using Django's method
|
||||||
assigned_students = random.sample(students, num_children)
|
password = 'parent123'
|
||||||
for student in assigned_students:
|
parent.set_password(password)
|
||||||
parent.students.add(student)
|
|
||||||
|
# Add parent to group
|
||||||
parents.append(parent)
|
parent.groups.add(parent_group)
|
||||||
self.stdout.write(self.style.SUCCESS(f'Created parent: {parent.name} with {num_children} children'))
|
|
||||||
|
# Assign students to parent if available
|
||||||
|
if students:
|
||||||
|
num_children = min(2, len(students))
|
||||||
|
if num_children > 0:
|
||||||
|
assigned_students = random.sample(students, num_children)
|
||||||
|
for student in assigned_students:
|
||||||
|
parent.students.add(student)
|
||||||
|
|
||||||
|
self.stdout.write(self.style.SUCCESS(f'Created parent: {parent.name} with phone {phone} (password: {password}) with {num_children} children'))
|
||||||
|
else:
|
||||||
|
self.stdout.write(self.style.SUCCESS(f'Created parent: {parent.name} with phone {phone} (password: {password}) with no children'))
|
||||||
|
|
||||||
|
parents.append(parent)
|
||||||
|
except Exception as e:
|
||||||
|
self.stdout.write(self.style.ERROR(f'Error creating parent: {str(e)}'))
|
||||||
|
continue
|
||||||
|
|
||||||
return parents
|
return parents
|
||||||
|
|
||||||
@@ -853,39 +942,41 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
# Calculate dates based on student's joining date
|
# Calculate dates based on student's joining date
|
||||||
joining_date = student.joining_date or datetime.now().date() - timedelta(days=random.randint(180, 365))
|
joining_date = student.joining_date or datetime.now().date() - timedelta(days=random.randint(180, 365))
|
||||||
expected_end_date = joining_date + timedelta(days=365 * course.duration)
|
|
||||||
|
|
||||||
# Calculate completion percentage based on current semester
|
# Calculate expected end date based on course duration type
|
||||||
if course.duration_type == 'Semester':
|
if course.duration_type == "Year":
|
||||||
total_semesters = course.duration * 2
|
years = course.duration
|
||||||
completion_percentage = int((student.current_period / total_semesters) * 100)
|
duration_days = years * 365
|
||||||
|
else: # Semester based
|
||||||
|
years = course.duration
|
||||||
|
duration_days = years * 365 # Use full years for total duration
|
||||||
|
|
||||||
|
expected_end_date = joining_date + timedelta(days=duration_days)
|
||||||
|
|
||||||
|
# Set period dates based on duration type
|
||||||
|
period_start_date = joining_date
|
||||||
|
if course.duration_type == "Semester":
|
||||||
|
period_end_date = joining_date + timedelta(days=180) # 6 months
|
||||||
else:
|
else:
|
||||||
completion_percentage = int((student.current_period / course.duration) * 100)
|
period_end_date = joining_date + timedelta(days=365) # 1 year
|
||||||
|
|
||||||
# Determine progress status
|
# Create course tracking - save() will automatically update completion percentage
|
||||||
if completion_percentage == 100:
|
with transaction.atomic():
|
||||||
progress_status = 'Completed'
|
course_tracking = CourseTracking.objects.create(
|
||||||
elif completion_percentage == 0:
|
student=student,
|
||||||
progress_status = 'Not Started'
|
course=course,
|
||||||
else:
|
enrollment_date=joining_date,
|
||||||
progress_status = 'In Progress'
|
start_date=joining_date,
|
||||||
|
expected_end_date=expected_end_date,
|
||||||
tracking = CourseTracking(
|
current_period=student.current_period,
|
||||||
student=student,
|
period_start_date=period_start_date,
|
||||||
course=course,
|
period_end_date=period_end_date,
|
||||||
enrollment_date=joining_date,
|
progress_status="In Progress",
|
||||||
start_date=joining_date,
|
notes=fake.paragraph() if random.random() < 0.3 else None
|
||||||
expected_end_date=expected_end_date,
|
)
|
||||||
actual_end_date=None,
|
|
||||||
progress_status=progress_status,
|
self.stdout.write(self.style.SUCCESS(f'Created course tracking for student: {student.name} in course: {course.name}'))
|
||||||
completion_percentage=completion_percentage,
|
|
||||||
current_period=student.current_period,
|
|
||||||
semester_start_date=joining_date,
|
|
||||||
notes=f"Tracking student progress in {course.name}"
|
|
||||||
)
|
|
||||||
tracking.save()
|
|
||||||
self.stdout.write(self.style.SUCCESS(f'Created course tracking for {student.name} in {course.name}'))
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Log the error but continue with other students
|
self.stdout.write(self.style.ERROR(f'Error creating course tracking for student {student.name}: {str(e)}'))
|
||||||
self.stdout.write(self.style.ERROR(f'Error creating course tracking for {student.name}: {str(e)}'))
|
continue
|
||||||
continue # Continue with next student
|
|
||||||
+88
-46
@@ -29,6 +29,13 @@ from app.models import (
|
|||||||
TOTPSecret,
|
TOTPSecret,
|
||||||
ResetToken,
|
ResetToken,
|
||||||
OTPAttempt,
|
OTPAttempt,
|
||||||
|
AttendanceRecord,
|
||||||
|
StudentLeave,
|
||||||
|
Attendance,
|
||||||
|
ParentFeedback,
|
||||||
|
ParentInstituteFeedback,
|
||||||
|
Routine,
|
||||||
|
SubjectFile,
|
||||||
)
|
)
|
||||||
from app.utils import cleanup_expired_tokens
|
from app.utils import cleanup_expired_tokens
|
||||||
|
|
||||||
@@ -479,15 +486,22 @@ def cleanup_orphaned_student_data(sender, instance, **kwargs):
|
|||||||
Clean up orphaned data when a student is deleted
|
Clean up orphaned data when a student is deleted
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
with transaction.atomic():
|
# Handle cleanup safely without relying on the model's method
|
||||||
# Clean up related records
|
# Delete attendance records
|
||||||
instance.cleanup_orphaned_data()
|
AttendanceRecord.objects.filter(student=instance).delete()
|
||||||
logger.info(f"Cleaned up orphaned data for deleted student: {instance.id}")
|
|
||||||
|
# Delete course tracking
|
||||||
# Clear any cached data
|
CourseTracking.objects.filter(student=instance).delete()
|
||||||
cache.delete_pattern(f"student_{instance.id}_*")
|
|
||||||
if instance.parent:
|
# Delete leave requests
|
||||||
cache.delete_pattern(f"parent_{instance.parent.id}_*")
|
StudentLeave.objects.filter(student=instance).delete()
|
||||||
|
|
||||||
|
# Clear any cached data
|
||||||
|
cache.delete(f"student_{instance.id}_profile")
|
||||||
|
cache.delete(f"student_{instance.id}_progress")
|
||||||
|
cache.delete(f"student_{instance.id}_attendance")
|
||||||
|
|
||||||
|
logger.info(f"Cleaned up orphaned data for deleted student: {instance.id}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error cleaning up orphaned student data: {str(e)}")
|
logger.error(f"Error cleaning up orphaned student data: {str(e)}")
|
||||||
|
|
||||||
@@ -497,13 +511,18 @@ def cleanup_orphaned_staff_data(sender, instance, **kwargs):
|
|||||||
Clean up orphaned data when a staff member is deleted
|
Clean up orphaned data when a staff member is deleted
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
with transaction.atomic():
|
# Handle cleanup safely without relying on the model's method
|
||||||
# Clean up related records
|
# Delete attendance records where this staff is the teacher
|
||||||
instance.cleanup_orphaned_data()
|
Attendance.objects.filter(teacher=instance).delete()
|
||||||
logger.info(f"Cleaned up orphaned data for deleted staff: {instance.id}")
|
|
||||||
|
# Clear course relationships
|
||||||
# Clear any cached data
|
instance.courses_taught.clear()
|
||||||
cache.delete_pattern(f"staff_{instance.id}_*")
|
|
||||||
|
# Clear any cached data
|
||||||
|
cache.delete(f"staff_{instance.id}_profile")
|
||||||
|
cache.delete(f"staff_{instance.id}_schedule")
|
||||||
|
|
||||||
|
logger.info(f"Cleaned up orphaned data for deleted staff: {instance.id}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error cleaning up orphaned staff data: {str(e)}")
|
logger.error(f"Error cleaning up orphaned staff data: {str(e)}")
|
||||||
|
|
||||||
@@ -513,15 +532,15 @@ def cleanup_orphaned_course_tracking_data(sender, instance, **kwargs):
|
|||||||
Clean up orphaned data when a course tracking record is deleted
|
Clean up orphaned data when a course tracking record is deleted
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
with transaction.atomic():
|
# No need for transaction, just clear cache
|
||||||
# Clean up related records
|
# CourseTracking doesn't have its own cleanup_orphaned_data method
|
||||||
instance.cleanup_orphaned_data()
|
|
||||||
logger.info(f"Cleaned up orphaned data for deleted course tracking: {instance.id}")
|
# Clear any cached data - use individual deletions instead of patterns
|
||||||
|
cache.delete(f"course_tracking_{instance.id}_percentage")
|
||||||
# Clear any cached data
|
if instance.student:
|
||||||
cache.delete_pattern(f"course_tracking_{instance.id}_*")
|
cache.delete(f"student_{instance.student.id}_progress")
|
||||||
if instance.student:
|
|
||||||
cache.delete_pattern(f"student_{instance.student.id}_*")
|
logger.info(f"Cleaned up cached data for deleted course tracking: {instance.id}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error cleaning up orphaned course tracking data: {str(e)}")
|
logger.error(f"Error cleaning up orphaned course tracking data: {str(e)}")
|
||||||
|
|
||||||
@@ -531,13 +550,18 @@ def cleanup_orphaned_parent_data(sender, instance, **kwargs):
|
|||||||
Clean up orphaned data when a parent is deleted
|
Clean up orphaned data when a parent is deleted
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
with transaction.atomic():
|
# Handle cleanup safely without relying on the model's method
|
||||||
# Clean up related records
|
# Delete feedback records
|
||||||
instance.cleanup_orphaned_data()
|
ParentFeedback.objects.filter(parent=instance).delete()
|
||||||
logger.info(f"Cleaned up orphaned data for deleted parent: {instance.id}")
|
|
||||||
|
# Delete institute feedback
|
||||||
# Clear any cached data
|
ParentInstituteFeedback.objects.filter(parent=instance).delete()
|
||||||
cache.delete_pattern(f"parent_{instance.id}_*")
|
|
||||||
|
# Clear any cached data
|
||||||
|
cache.delete(f"parent_{instance.id}_profile")
|
||||||
|
cache.delete(f"parent_{instance.id}_students")
|
||||||
|
|
||||||
|
logger.info(f"Cleaned up orphaned data for deleted parent: {instance.id}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error cleaning up orphaned parent data: {str(e)}")
|
logger.error(f"Error cleaning up orphaned parent data: {str(e)}")
|
||||||
|
|
||||||
@@ -547,13 +571,21 @@ def cleanup_orphaned_course_data(sender, instance, **kwargs):
|
|||||||
Clean up orphaned data when a course is deleted
|
Clean up orphaned data when a course is deleted
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
with transaction.atomic():
|
# Handle cleanup safely without relying on the model's method
|
||||||
# Clean up related records
|
# Delete subjects
|
||||||
instance.cleanup_orphaned_data()
|
Subject.objects.filter(course=instance).delete()
|
||||||
logger.info(f"Cleaned up orphaned data for deleted course: {instance.id}")
|
|
||||||
|
# Delete course tracking records
|
||||||
# Clear any cached data
|
CourseTracking.objects.filter(course=instance).delete()
|
||||||
cache.delete_pattern(f"course_{instance.id}_*")
|
|
||||||
|
# Delete routines
|
||||||
|
Routine.objects.filter(course=instance).delete()
|
||||||
|
|
||||||
|
# Clear any cached data
|
||||||
|
cache.delete(f"course_{instance.id}_details")
|
||||||
|
cache.delete(f"course_{instance.id}_subjects")
|
||||||
|
|
||||||
|
logger.info(f"Cleaned up orphaned data for deleted course: {instance.id}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error cleaning up orphaned course data: {str(e)}")
|
logger.error(f"Error cleaning up orphaned course data: {str(e)}")
|
||||||
|
|
||||||
@@ -563,13 +595,23 @@ def cleanup_orphaned_subject_data(sender, instance, **kwargs):
|
|||||||
Clean up orphaned data when a subject is deleted
|
Clean up orphaned data when a subject is deleted
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
with transaction.atomic():
|
# Handle cleanup safely without relying on the model's method
|
||||||
# Clean up related records
|
# Delete subject files
|
||||||
instance.cleanup_orphaned_data()
|
SubjectFile.objects.filter(subject=instance).delete()
|
||||||
logger.info(f"Cleaned up orphaned data for deleted subject: {instance.id}")
|
|
||||||
|
# Delete routines
|
||||||
# Clear any cached data
|
Routine.objects.filter(subject=instance).delete()
|
||||||
cache.delete_pattern(f"subject_{instance.id}_*")
|
|
||||||
|
# Delete attendance records
|
||||||
|
attendances = Attendance.objects.filter(routine__subject=instance)
|
||||||
|
for attendance in attendances:
|
||||||
|
attendance.delete()
|
||||||
|
|
||||||
|
# Clear any cached data
|
||||||
|
cache.delete(f"subject_{instance.id}_details")
|
||||||
|
cache.delete(f"subject_{instance.id}_files")
|
||||||
|
|
||||||
|
logger.info(f"Cleaned up orphaned data for deleted subject: {instance.id}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error cleaning up orphaned subject data: {str(e)}")
|
logger.error(f"Error cleaning up orphaned subject data: {str(e)}")
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user