This commit is contained in:
AN 2025-01-15 14:34:15 +00:00 committed by GitHub
parent 11c20c0474
commit f038e97354
7 changed files with 57 additions and 19 deletions

View file

@ -10,13 +10,13 @@ class CourseAdmin(admin.ModelAdmin):
@admin.register(Module)
class ModuleAdmin(admin.ModelAdmin):
list_display = ('id', 'title', 'course', 'order')
list_display = ('id', 'title', 'course')
search_fields = ('title', 'course__title')
list_filter = ('course',)
@admin.register(Lesson)
class LessonAdmin(admin.ModelAdmin):
list_display = ('title', 'module', 'order')
list_display = ('title', 'module')
search_fields = ('title', 'module__title')
list_filter = ('module',)

View file

@ -0,0 +1,21 @@
# Generated by Django 5.0.10 on 2025-01-14 17:20
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('app', '0009_lesson_description_alter_module_description'),
]
operations = [
migrations.RemoveField(
model_name='lesson',
name='order',
),
migrations.RemoveField(
model_name='module',
name='order',
),
]

View file

@ -35,7 +35,6 @@ class Module(models.Model):
title = models.CharField(max_length=255, verbose_name="Module Title")
description = models.TextField(null=True, verbose_name="Module Description")
course = models.ForeignKey(Course, on_delete=models.CASCADE, related_name='modules', verbose_name="Course")
order = models.PositiveIntegerField(default=0, verbose_name="Order", unique=True)
created_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, verbose_name="Created By")
def str(self):
@ -48,7 +47,6 @@ class Lesson(models.Model):
description = models.TextField(null=True, verbose_name="Lesson Description")
content = models.TextField(verbose_name="Lesson Content")
module = models.ForeignKey(Module, on_delete=models.CASCADE, related_name='lessons', verbose_name="Module")
order = models.PositiveIntegerField(default=0, verbose_name="Order")
file = models.FileField(upload_to='lesson_files/', null=True, blank=True, verbose_name="Attached File")
created_by = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True, verbose_name="Created By")

View file

@ -21,6 +21,9 @@ class IsOwnerOrReadOnly(BasePermission):
case "LessonViewSet":
return obj.created_by == request.user
case "EnrollmentViewSet":
return obj.student == request.user

View file

@ -24,20 +24,21 @@ class LessonSerializer(serializers.ModelSerializer):
class Meta:
model = Lesson
fields = ['id', 'title', 'description', 'content', 'module', 'order', 'file']
fields = ['id', 'title', 'description', 'content', 'module', 'file']
class ModuleSerializer(serializers.ModelSerializer):
lessons = serializers.SerializerMethodField()
class Meta:
model = Module
fields = ['id', 'title', 'description', 'lessons', 'course', 'order']
fields = ['id', 'title', 'description', 'lessons', 'course']
read_only_fields = ['course', 'lessons']
def get_lessons(self, obj):
return obj.lessons.values('id', 'title', 'description')
class EnrollmentSerializer(serializers.ModelSerializer):
course_details = serializers.SerializerMethodField()
class Meta:

3
lms/app/signals.py Normal file
View file

@ -0,0 +1,3 @@
from django.db.models.signals import pre_save
from django.dispatch import receiver
from .model import Module

View file

@ -55,7 +55,7 @@ class ModuleViewSet(ModelViewSet):
if course_id:
course = Course.objects.filter(id=course_id).first()
if course:
return Module.objects.filter(course=course).order_by('order')
return Module.objects.filter(course=course)
return Module.objects.none()
@ -65,6 +65,10 @@ class ModuleViewSet(ModelViewSet):
"""
course_id = self.request.data.get('course')
course = Course.objects.filter(id=course_id, owner=self.request.user).first()
is_owner = course.owner == self.request.user
if not is_owner:
raise PermissionDenied("You do not have permission to create module.")
if not course:
return Response(
{"detail": "This course not found."},
@ -108,10 +112,27 @@ class LessonViewSet(ModelViewSet):
is_enrolled = Enrollment.objects.filter(course=module.course, student=self.request.user).exists()
if is_owner or is_enrolled:
return Lesson.objects.filter(id=lesson_id) # Return the lesson if the user is authorized
return Lesson.objects.none() # Deny access if the user is not authorized
def perform_create(self, serializer):
"""
Customize the creation of a lesson to include the module and the user who created it.
"""
module_id = self.request.data.get('module') # Get the module ID from the request
module = Module.objects.filter(id=module_id).first() # Fetch the module
is_owner = module.course.owner == self.request.user
if not is_owner:
raise PermissionDenied("You do not have permission to create lessons in this module.")
if not module:
raise serializers.ValidationError({"module": "Module does not exist."})
# Save the lesson with the module and created_by user
serializer.save(module=module, created_by=self.request.user)
class EnrollmentViewSet(ModelViewSet):
@ -120,10 +141,10 @@ class EnrollmentViewSet(ModelViewSet):
permission_classes = [IsAuthenticated]
http_method_names = ['get', 'post', 'delete']
def retrieve(self, request, *args, **kwargs):
instance = Enrollment.objects.filter(user=request.user)
def list(self, request, *args, **kwargs):
instance = Enrollment.objects.filter(student=request.user)
serializer = self.get_serializer(instance)
serializer = self.get_serializer(instance, many=True)
return Response(serializer.data)
@ -147,15 +168,6 @@ class EnrollmentViewSet(ModelViewSet):
serializer = self.get_serializer(enrollment)
return Response(serializer.data, status=status.HTTP_201_CREATED)
def destroy(self, request, *args, **kwargs):
# Get the enrollment object to delete
enrollment = self.get_object()
if enrollment.student != request.user:
raise PermissionDenied("You do not have permission to delete this enrollment.")
# Delete the enrollment
enrollment.delete()
return Response({"detail": "Enrollment deleted successfully"}, status=status.HTTP_204_NO_CONTENT)
class QuizViewSet(ModelViewSet):