This commit is contained in:
AN 2025-01-12 14:39:59 +00:00 committed by GitHub
parent 300a1efc4e
commit 19907b1e83
10 changed files with 168 additions and 82 deletions

View file

@ -0,0 +1,35 @@
from django.contrib.auth import get_user_model
User = get_user_model()
class TransitionManager:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# هذه الخطوة تتم قبل وصول الطلب إلى الفيو
print("قبل معالجة الطلب")
# تمرير الطلب إلى الفيو والحصول على الاستجابة
response = self.get_response(request)
# التحقق من وجود المستخدم
try:
user = User.objects.get(email=request.user.email)
match user.role:
case "student":
print("طالب")
case "instructor":
print("instructor")
case "admin":
print("مشرف")
case _:
print("القيمة غير معروفة")
except User.DoesNotExist:
print("المستخدم غير موجود")
print("بعد معالجة الطلب")
return response

View file

@ -0,0 +1,18 @@
# Generated by Django 5.0.10 on 2025-01-12 14:39
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0007_remove_customuser_username_and_more'),
]
operations = [
migrations.AddField(
model_name='customuser',
name='image',
field=models.ImageField(blank=True, null=True, upload_to='account/profile_image/'),
),
]

View file

@ -19,27 +19,25 @@ class CustomUserManager(BaseUserManager):
class CustomUser(AbstractUser):
# إزالة الحقل username من AbstractUser
ROLE_CHOICES = {
'student': 'Student',
'instructor': 'Instructor',
'admin': 'Admin',
}
username = None
first_name = None
last_name = None
# الحقول الخاصة بالمستخدم المخصص
email = models.EmailField(unique=True)
full_name = models.CharField(max_length=255, null=True, blank=True)
ROLE_CHOICES = [
('student', 'Student'),
('instructor', 'Instructor'),
('admin', 'Admin'),
]
image = models.ImageField(upload_to="account/profile_image/", null=True, blank=True)
role = models.CharField(max_length=20, choices=ROLE_CHOICES, null=True, blank=True)
# تخصيص مدير المستخدم
objects = CustomUserManager()
# تحديد الحقول الأساسية
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = [] # قائمة الحقول المطلوبة لإنشاء مستخدم عبر createsuperuser
REQUIRED_FIELDS = []
def __str__(self):
return self.email

View file

@ -0,0 +1,18 @@
# Generated by Django 5.0.10 on 2025-01-12 10:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='course',
name='image',
field=models.ImageField(null=True, upload_to='courses/image'),
),
]

View file

@ -0,0 +1,23 @@
# Generated by Django 5.0.10 on 2025-01-12 10:16
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0002_course_image'),
]
operations = [
migrations.AddField(
model_name='course',
name='is_paid',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='course',
name='price',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=10, null=True),
),
]

View file

@ -0,0 +1,18 @@
# Generated by Django 5.0.10 on 2025-01-12 14:39
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app', '0003_course_is_paid_course_price'),
]
operations = [
migrations.AddField(
model_name='course',
name='rating',
field=models.PositiveSmallIntegerField(blank=True, null=True),
),
]

View file

@ -1,7 +1,7 @@
from django.db import models
from uuid import uuid4
from django.contrib.auth import get_user_model
from rest_framework.exceptions import ValidationError
User = get_user_model()
@ -10,12 +10,24 @@ class Course(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4, editable=False)
title = models.CharField(max_length=255, verbose_name="Course Title")
description = models.TextField(verbose_name="Course Description")
instructor = models.ForeignKey(User, on_delete=models.CASCADE, related_name='courses_taught', verbose_name="Instructor")
image = models.ImageField(upload_to="courses/image", null=True)
is_paid = models.BooleanField(default=False)
price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
instructor = models.ForeignKey(User, on_delete=models.CASCADE, related_name='courses_taught', verbose_name="Instructor")
rating = models.PositiveSmallIntegerField(null=True, blank=True)
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 self.title
def clean(self):
if self.is_paid and (self.price is None or self.price <= 0):
raise ValidationError({'price': 'Price must be set and greater than 0 for paid products.'})
if not self.is_paid and self.price:
raise ValidationError({'price': 'Price must be empty for free products.'})
# Table for modules (Module)
class Module(models.Model):

View file

@ -7,79 +7,15 @@ from allauth.account.models import EmailAddress
from dj_rest_auth.registration.serializers import RegisterSerializer
class CustomLoginSerializer(LoginSerializer):
email = serializers.EmailField(required=True)
password = serializers.CharField(style={'input_type': 'password'})
def validate(self, attrs):
email = attrs.get('email')
password = attrs.get('password')
if not email or not password:
raise serializers.ValidationError("Please enter both email and password.")
User = get_user_model()
users = User.objects.filter(email=email)
if not users.exists():
raise serializers.ValidationError("Incorrect email.")
if users.count() > 1:
raise serializers.ValidationError("Multiple users found with this email. Please contact support.")
user = users.first()
if not user.check_password(password):
raise serializers.ValidationError("Incorrect password.")
if not self.is_email_verified(user):
raise serializers.ValidationError("Email not verified. Please verify your email first.")
attrs['user'] = user
return attrs
def is_email_verified(self, user):
if hasattr(user, 'email_verified'):
return user.email_verified
else:
try:
email_address = EmailAddress.objects.get(user=user, email=user.email)
return email_address.verified
except EmailAddress.DoesNotExist:
return False
class CustomRegisterSerializer(RegisterSerializer):
full_name = serializers.CharField(required=True)
def save(self, request):
user = super().save(request)
user.full_name = self.data.get('full_name', '')
user.save()
return user
class CourseSerializer(serializers.HyperlinkedModelSerializer):
class CourseSerializer(serializers.ModelSerializer):
instructor_name = serializers.CharField(source='instructor.username', read_only=True)
class Meta:
model = Course
fields = ['url', 'id', 'title', 'description', 'instructor_name', 'created_at', 'updated_at']
fields = ['id', 'title', 'description', 'is_paid', 'price', 'image', 'instructor_name', 'created_at', 'updated_at']
read_only_fields = ['created_at', 'updated_at']
class ModuleSerializer(serializers.HyperlinkedModelSerializer):
class Meta:

View file

@ -3,6 +3,7 @@ from .views import *
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'courses-read', CourseRead, basename='course-read')
router.register(r'courses', CourseViewSet, basename='course')
router.register(r'modules', ModuleViewSet, basename='modules')
router.register(r'lessons', LessonViewSet, basename='lessons')

View file

@ -1,25 +1,44 @@
from django.shortcuts import render
from .serializers import *
from .models import *
from rest_framework.viewsets import ModelViewSet
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
from rest_framework.response import Response
from rest_framework import status
from rest_framework.permissions import IsAuthenticated, BasePermission
from .permissions import IsInstructor, IsAdmin
class CourseRead(ReadOnlyModelViewSet):
permission_classes = [IsAuthenticated]
serializer_class = CourseSerializer
queryset = Course.objects.all()
class CourseViewSet(ModelViewSet):
"""
A ViewSet for viewing and editing Course instances.
"""
permission_classes = [IsAuthenticated,]
queryset = Course.objects.all()
serializer_class = CourseSerializer
def get_queryset(self):
"""
Return courses belonging to the authenticated user.
"""
user = self.request.user
return Course.objects.filter(instructor=user)
def perform_create(self, serializer):
"""
Save the post data when creating a new course.
"""
serializer.save(instructor=self.request.user)
user = self.request.user
serializer.save(instructor=user)
def perform_update(self, serializer):
"""
@ -44,6 +63,14 @@ class CourseViewSet(ModelViewSet):
)
instance.delete()
class ModuleViewSet(ModelViewSet):
"""
ViewSet for managing modules.