This commit is contained in:
Ahmed Nagi 2025-01-21 13:51:06 +00:00
parent aae1451eeb
commit d24197b6c9
7 changed files with 17 additions and 98 deletions

View file

@ -1,4 +1,4 @@
# Generated by Django 5.0.10 on 2025-01-15 15:19 # Generated by Django 5.0.10 on 2025-01-21 13:50
import django.utils.timezone import django.utils.timezone
from django.db import migrations, models from django.db import migrations, models

View file

@ -1,4 +1,4 @@
# Generated by Django 5.0.10 on 2025-01-15 15:19 # Generated by Django 5.0.10 on 2025-01-21 13:50
import django.db.models.deletion import django.db.models.deletion
import uuid import uuid
@ -15,6 +15,16 @@ class Migration(migrations.Migration):
] ]
operations = [ operations = [
migrations.CreateModel(
name='AD',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255)),
('description', models.TextField()),
('image', models.ImageField(blank=True, null=True, upload_to='ads_images/')),
('created_at', models.DateTimeField(auto_now_add=True)),
],
),
migrations.CreateModel( migrations.CreateModel(
name='Course', name='Course',
fields=[ fields=[
@ -27,7 +37,7 @@ class Migration(migrations.Migration):
('rating', models.PositiveSmallIntegerField(blank=True, null=True)), ('rating', models.PositiveSmallIntegerField(blank=True, null=True)),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='courses_taught', to=settings.AUTH_USER_MODEL, verbose_name='Instructor')), ('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='owner', to=settings.AUTH_USER_MODEL, verbose_name='Owner')),
], ],
), ),
migrations.CreateModel( migrations.CreateModel(
@ -47,7 +57,7 @@ class Migration(migrations.Migration):
('enrolled_at', models.DateTimeField(auto_now_add=True, verbose_name='Enrollment Date')), ('enrolled_at', models.DateTimeField(auto_now_add=True, verbose_name='Enrollment Date')),
('completed', models.BooleanField(default=False, verbose_name='Completed')), ('completed', models.BooleanField(default=False, verbose_name='Completed')),
('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='enrollments', to='app.course', verbose_name='Course')), ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='enrollments', to='app.course', verbose_name='Course')),
('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='enrollments', to=settings.AUTH_USER_MODEL, verbose_name='Student')), ('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='students_enrollments', to=settings.AUTH_USER_MODEL, verbose_name='Student')),
], ],
), ),
migrations.CreateModel( migrations.CreateModel(
@ -68,17 +78,9 @@ class Migration(migrations.Migration):
('description', models.TextField(null=True, verbose_name='Lesson Description')), ('description', models.TextField(null=True, verbose_name='Lesson Description')),
('content', models.TextField(verbose_name='Lesson Content')), ('content', models.TextField(verbose_name='Lesson Content')),
('file', models.FileField(blank=True, null=True, upload_to='lesson_files/', verbose_name='Attached File')), ('file', models.FileField(blank=True, null=True, upload_to='lesson_files/', verbose_name='Attached File')),
('quiz', models.JSONField(null=True)),
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Created By')), ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL, verbose_name='Created By')),
('module', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='lessons', to='app.module', verbose_name='Module')), ('module', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='lessons', to='app.module', verbose_name='Module')),
], ],
), ),
migrations.CreateModel(
name='Quiz',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('title', models.CharField(max_length=255, verbose_name='Quiz Title')),
('questions', models.JSONField(null=True, verbose_name='Questions')),
('module', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='quiz', to='app.module', verbose_name='Module')),
],
),
] ]

View file

@ -1,29 +0,0 @@
# Generated by Django 5.0.10 on 2025-01-19 09:26
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AddField(
model_name='lesson',
name='quiz',
field=models.JSONField(null=True),
),
migrations.AlterField(
model_name='enrollment',
name='student',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='students_enrollments', to=settings.AUTH_USER_MODEL, verbose_name='Student'),
),
migrations.DeleteModel(
name='Quiz',
),
]

View file

@ -1,31 +0,0 @@
# Generated by Django 5.0.10 on 2025-01-21 09:33
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0002_lesson_quiz_alter_enrollment_student_delete_quiz'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Advertisement',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=255)),
('description', models.TextField()),
('image', models.ImageField(blank=True, null=True, upload_to='ads_images/')),
('created_at', models.DateTimeField(auto_now_add=True)),
],
),
migrations.AlterField(
model_name='course',
name='owner',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='owner', to=settings.AUTH_USER_MODEL, verbose_name='Owner'),
),
]

View file

@ -1,17 +0,0 @@
# Generated by Django 5.0.10 on 2025-01-21 10:43
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('app', '0003_advertisement_alter_course_owner'),
]
operations = [
migrations.RenameModel(
old_name='Advertisement',
new_name='AD',
),
]

View file

@ -74,7 +74,6 @@ class Certificate(models.Model):
class AD(models.Model): class AD(models.Model):
title = models.CharField(max_length=255) title = models.CharField(max_length=255)
description = models.TextField() description = models.TextField()

View file

@ -145,23 +145,20 @@ class LessonViewSet(ModelViewSet):
""" """
Custom PATCH method to update a lesson. Custom PATCH method to update a lesson.
""" """
# الحصول على معرف الكائن (lesson_id) من الـ URL
lesson_id = self.request.query_params.get('lesson_id') lesson_id = self.request.query_params.get('lesson_id')
if not lesson_id: if not lesson_id:
raise CustomValidationError({"detail": "Lesson ID is required in the URL."}, status=status.HTTP_400_BAD_REQUEST) raise CustomValidationError({"detail": "Lesson ID is required in the URL."}, status=status.HTTP_400_BAD_REQUEST)
# البحث عن الدرس
lesson = Lesson.objects.filter(id=lesson_id).first() lesson = Lesson.objects.filter(id=lesson_id).first()
if not lesson: if not lesson:
raise CustomValidationError({"detail": "Lesson not found."}, status=status.HTTP_404_NOT_FOUND) raise CustomValidationError({"detail": "Lesson not found."}, status=status.HTTP_404_NOT_FOUND)
# التحقق من الصلاحيات (مالك الكورس أو مسجل فيه)
is_owner = lesson.module.course.owner == request.user is_owner = lesson.module.course.owner == request.user
if not is_owner: if not is_owner:
raise PermissionDenied("You do not have permission to update this lesson.") raise PermissionDenied("You do not have permission to update this lesson.")
# تحديث الدرس باستخدام البيانات المرسلة في الطلب
serializer = self.get_serializer(lesson, data=request.data, partial=True) # partial=True لتحديث الحقول المطلوبة فقط serializer = self.get_serializer(lesson, data=request.data, partial=True) # partial=True لتحديث الحقول المطلوبة فقط
if serializer.is_valid(): if serializer.is_valid():
serializer.save() serializer.save()
@ -185,7 +182,7 @@ class LessonViewSet(ModelViewSet):
status=status.HTTP_400_BAD_REQUEST status=status.HTTP_400_BAD_REQUEST
) )
# البحث عن الدرس
try: try:
lesson = Lesson.objects.get(id=lesson_id) lesson = Lesson.objects.get(id=lesson_id)
except Lesson.DoesNotExist: except Lesson.DoesNotExist:
@ -194,13 +191,11 @@ class LessonViewSet(ModelViewSet):
status=status.HTTP_404_NOT_FOUND status=status.HTTP_404_NOT_FOUND
) )
# التحقق من الصلاحيات (مالك الكورس أو مسجل فيه)
is_owner = lesson.module.course.owner == request.user is_owner = lesson.module.course.owner == request.user
if not is_owner: if not is_owner:
raise PermissionDenied("You do not have permission to delete this lesson.") raise PermissionDenied("You do not have permission to delete this lesson.")
# حذف الدرس
lesson.delete() lesson.delete()
return Response( return Response(