You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

125 lines
4.9 KiB

from apps.course.models import Course
from apps.chat.models import RoomMessage
from apps.course.models.course import Course
from apps.course.models.lesson import CourseLesson
from django.db.models import Q
from django.db.models.signals import post_save, post_delete, pre_save
from django.dispatch import receiver
from django.core.cache import cache
from django.contrib.auth import get_user_model
UserModel = get_user_model()
@receiver(post_save, sender=Course)
def handle_room_message_for_course(sender, instance, created, **kwargs):
if created: # فقط برای موارد جدید اجرا شود
RoomMessage.objects.create(
name=f"{instance.title} - Group",
description=f"Group chat for course: {instance.title}",
initiator=instance.professor, # استاد به‌عنوان سازنده اتاق
course=instance,
room_type=RoomMessage.RoomTypeChoices.GROUP
)
else: # این بخش در زمان آپدیت دوره اجرا می‌شود
# Find the existing group room for this course and update its details
RoomMessage.objects.filter(
course=instance,
room_type=RoomMessage.RoomTypeChoices.GROUP
).update(
name=f"{instance.title} - Group",
description=f"Group chat for course: {instance.title}",
initiator=instance.professor
)
@receiver(post_save, sender=Course)
def ensure_professor_role(sender, instance, **kwargs):
professor = getattr(instance, 'professor', None)
if professor:
professor.ensure_professor_profile()
@receiver([post_save, post_delete], sender=Course)
def invalidate_professor_course_cache(sender, instance, **kwargs):
"""
Clears the cached professor detail page AND their course list
whenever a course assigned to them is created, updated, or deleted.
"""
if instance.professor:
detail_cache_key = f"professor_detail_{instance.professor.slug}"
cache.delete(detail_cache_key)
# Optional: If you update a Professor's profile in the admin directly
@receiver([post_save, post_delete], sender=UserModel)
def invalidate_professor_profile_cache(sender, instance, **kwargs):
if instance.user_type == UserModel.UserType.PROFESSOR:
cache_key = f"professor_detail_{instance.slug}"
cache.delete(cache_key)
@receiver(post_save, sender=Course)
def sync_course_chat_locks(sender, instance, **kwargs):
"""
Automatically locks/unlocks the related chat rooms when the admin
toggles the chat locks on the Course page.
"""
# 1. Update the Group Chat
RoomMessage.objects.filter(
course=instance,
room_type=RoomMessage.RoomTypeChoices.GROUP
).update(is_locked=instance.is_group_chat_locked)
# 2. Update the Private Chats between the Professor and Students of this course
# Get all student IDs enrolled in this course
student_ids = instance.participants.values_list('student_id', flat=True)
if student_ids:
RoomMessage.objects.filter(
room_type=RoomMessage.RoomTypeChoices.PRIVATE
).filter(
# Find rooms where initiator is prof and recipient is student, OR vice versa
Q(initiator_id=instance.professor_id, recipient_id__in=student_ids) |
Q(initiator_id__in=student_ids, recipient_id=instance.professor_id)
).update(is_locked=instance.is_professor_chat_locked)
def _recalculate_course_lessons_count(course_id):
Course.recalculate_lessons_count_for_course(course_id)
@receiver(pre_save, sender=CourseLesson)
def capture_previous_course_lesson_state(sender, instance, **kwargs):
if not instance.pk:
instance._previous_course_id = None
instance._previous_is_active = None
return
previous = sender.objects.filter(pk=instance.pk).values('course_id', 'is_active').first()
if previous:
instance._previous_course_id = previous['course_id']
instance._previous_is_active = previous['is_active']
else:
instance._previous_course_id = None
instance._previous_is_active = None
@receiver(post_save, sender=CourseLesson)
def sync_lessons_count_on_course_lesson_save(sender, instance, **kwargs):
affected_course_ids = {instance.course_id}
previous_course_id = getattr(instance, '_previous_course_id', None)
previous_is_active = getattr(instance, '_previous_is_active', None)
if previous_course_id and previous_course_id != instance.course_id:
affected_course_ids.add(previous_course_id)
if previous_is_active is not None and previous_is_active != instance.is_active and previous_course_id:
affected_course_ids.add(previous_course_id)
for course_id in affected_course_ids:
_recalculate_course_lessons_count(course_id)
@receiver(post_delete, sender=CourseLesson)
def sync_lessons_count_on_course_lesson_delete(sender, instance, **kwargs):
_recalculate_course_lessons_count(instance.course_id)