diff --git a/apps/course/models/lesson.py b/apps/course/models/lesson.py index d300dfc..fd8ef10 100644 --- a/apps/course/models/lesson.py +++ b/apps/course/models/lesson.py @@ -44,6 +44,45 @@ class Lesson(models.Model): 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( diff --git a/apps/course/serializers/course.py b/apps/course/serializers/course.py index 7d03e7b..6f9639b 100644 --- a/apps/course/serializers/course.py +++ b/apps/course/serializers/course.py @@ -2,7 +2,7 @@ from rest_framework import serializers from dj_filer.admin import get_thumbs -from apps.course.models import Course, CourseCategory, Attachment, Glossary, LessonCompletion, Participant +from apps.course.models import Course, CourseCategory, Attachment, Glossary, LessonCompletion, Participant, Lesson from apps.account.serializers import UserProfileSerializer @@ -67,6 +67,7 @@ class CourseDetailSerializer(serializers.ModelSerializer): access = serializers.SerializerMethodField() lessons_complated_count = serializers.SerializerMethodField() lessons_count = serializers.SerializerMethodField() + last_lesson_id = serializers.SerializerMethodField() class Meta: model = Course @@ -96,8 +97,39 @@ class CourseDetailSerializer(serializers.ModelSerializer): 'final_price', 'timing', 'features', + 'last_lesson_id' ] + def get_last_lesson_id(self, obj): + request = self.context.get('request') + if request and request.user.is_authenticated: + user = request.user + + # آخرین درس تکمیل‌شده توسط کاربر + last_completed_lesson = LessonCompletion.objects.filter( + student=user, + lesson__course=obj + ).order_by('-completed_at').first() + + if last_completed_lesson: + # پیدا کردن درس بعدی بر اساس priority + next_lesson = Lesson.objects.filter( + course=obj, + priority__gt=last_completed_lesson.lesson.priority, + is_active=True + ).order_by('priority').first() + else: + # اگر هیچ درسی تکمیل نشده باشد، اولین درس را برگردان + next_lesson = Lesson.objects.filter( + course=obj, + is_active=True + ).order_by('priority').first() + if next_lesson: + return next_lesson.id + return None + + + def get_access(self, obj): if student := self._get_authenticated_user(): if not self._is_participant(student, obj): diff --git a/apps/course/views/lesson.py b/apps/course/views/lesson.py index 7492fa1..c4cde86 100644 --- a/apps/course/views/lesson.py +++ b/apps/course/views/lesson.py @@ -44,40 +44,60 @@ class LessonDetailView(RetrieveAPIView): def get(self, request, *args, **kwargs): lesson_id = self.kwargs.get('id') lesson = get_object_or_404(Lesson, id=lesson_id, is_active=True) - - # Get the next and previous lessons based on priority and id - next_lesson = Lesson.objects.filter( - course=lesson.course, - is_active=True, - priority__gte=lesson.priority, - id__gt=lesson.id - ).order_by('priority', 'id').first() - - previous_lesson = Lesson.objects.filter( - course=lesson.course, - is_active=True, - priority__lte=lesson.priority, - id__lt=lesson.id - ).order_by('-priority', '-id').first() - total_lessons = Lesson.objects.filter(course=lesson.course, is_active=True).count() - # Calculate the current lesson number in the course - current_lesson_number = Lesson.objects.filter( - course=lesson.course, - is_active=True, - priority__lte=lesson.priority - ).count() - - # Serialize the current lesson + + course = lesson.course + lessons = Lesson.objects.filter(course=course, is_active=True).order_by('priority') + + total_lessons = lessons.count() + current_lesson_number = list(lessons.values_list('id', flat=True)).index(lesson.id) + 1 + next_lesson = lessons.filter(priority__gt=lesson.priority).order_by('priority').first() + next_lesson_id = next_lesson.id if next_lesson else None + previous_lesson = lessons.filter(priority__lt=lesson.priority).order_by('-priority').first() + previous_lesson_id = previous_lesson.id if previous_lesson else None + lesson_data = self.get_serializer(lesson).data - # Add current lesson number and total lessons - lesson_data['current_lesson_number'] = current_lesson_number lesson_data['total_lessons'] = total_lessons + lesson_data['current_lesson_number'] = current_lesson_number + lesson_data['next_lesson_id'] = next_lesson_id + lesson_data['previous_lesson_id'] = previous_lesson_id + + + + + # # Get the next and previous lessons based on priority and id + # next_lesson = Lesson.objects.filter( + # course=lesson.course, + # is_active=True, + # priority__gte=lesson.priority, + # id__gt=lesson.id + # ).order_by('priority', 'id').first() + + # previous_lesson = Lesson.objects.filter( + # course=lesson.course, + # is_active=True, + # priority__lte=lesson.priority, + # id__lt=lesson.id + # ).order_by('-priority', '-id').first() + + # total_lessons = Lesson.objects.filter(course=lesson.course, is_active=True).count() + # # Calculate the current lesson number in the course + # current_lesson_number = Lesson.objects.filter( + # course=lesson.course, + # is_active=True, + # priority__lte=lesson.priority + # ).count() + + # # Serialize the current lesson + # lesson_data = self.get_serializer(lesson).data + # # Add current lesson number and total lessons + # lesson_data['current_lesson_number'] = current_lesson_number + # lesson_data['total_lessons'] = total_lessons - # Add next and previous lesson ids - lesson_data['next_lesson_id'] = next_lesson.id if next_lesson else None - lesson_data['previous_lesson_id'] = previous_lesson.id if previous_lesson else None + # # Add next and previous lesson ids + # lesson_data['next_lesson_id'] = next_lesson.id if next_lesson else None + # lesson_data['previous_lesson_id'] = previous_lesson.id if previous_lesson else None - lesson_data['can_go_next'] = next_lesson is not None + # lesson_data['can_go_next'] = next_lesson is not None return Response(lesson_data)