import os from django.db import models from django.utils.translation import gettext_lazy as _ from filer.fields.image import FilerImageField from filer.fields.file import FilerFileField from apps.account.models import StudentUser def lesson_file_upload_to(instance, filename): return os.path.join(f"courses/{instance.course.slug}/lessons/{filename}") class Lesson(models.Model): class ContentTypeChoices(models.TextChoices): YOUTUBE_LINK = 'youtube_link', 'Youtube Link' VIDEO_FILE = 'video_file', 'Video File' course = models.ForeignKey("course.Course", on_delete=models.CASCADE, related_name='lessons', verbose_name='Course') title = models.CharField(max_length=255, verbose_name='Lesson Title') priority = models.IntegerField(null=True, blank=True, verbose_name='Priority') is_active = models.BooleanField(default=True, verbose_name=_('Is Active')) duration = models.PositiveIntegerField(verbose_name='Duration (in minutes)') content_type = models.CharField(max_length=50, choices=ContentTypeChoices.choices, verbose_name='Content Type') content_file = models.FileField( null=True, blank=True, upload_to=lesson_file_upload_to, ) video_link = models.CharField(max_length=500, null=True, blank=True, verbose_name='Link') created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Created at")) updated_at = models.DateTimeField(auto_now=True, verbose_name=_("Updated At")) def __str__(self): return f"{self.course.title} - {self.title}" def is_completed_by(self, student): return self.completions.filter(student=student).exists() def save(self, *args, **kwargs): print(f'---> start') if self.priority is None: # If priority is not set, set it to the next available priority max_priority = self.course.lessons.aggregate(max_priority=models.Max('priority'))['max_priority'] self.priority = (max_priority or 0) + 1 else: self._adjust_priorities() super().save(*args, **kwargs) def _adjust_priorities(self): # Adjust priorities of other lessons in the course lessons = self.course.lessons.exclude(pk=self.pk) # Shift priorities for lessons with the same or higher priority lessons.filter(priority__gte=self.priority).update(priority=models.F('priority') + 1) # # If priority is set, adjust the priorities of other lessons # lessons = self.course.lessons.exclude(pk=self.pk).order_by('priority') # updated_priorities = [] # inserted = False # for lesson in lessons: # if lesson.priority >= self.priority and not inserted: # updated_priorities.append((self.priority, self)) # inserted = True # updated_priorities.append((lesson.priority if not inserted else lesson.priority + 1, lesson)) # if not inserted: # updated_priorities.append((self.priority, self)) # # Update priorities in bulk # for priority, lesson in updated_priorities: # lesson.priority = priority # lesson.save(update_fields=['priority']) class LessonCompletion(models.Model): student = models.ForeignKey( StudentUser, on_delete=models.CASCADE, related_name='lesson_completions' ) lesson = models.ForeignKey( Lesson, on_delete=models.CASCADE, related_name='completions' ) completed_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True, verbose_name=_("Created at")) class Meta: unique_together = ('student', 'lesson') def __str__(self): return f"{self.student.fullname} - {self.lesson.title} - Completed"