This commit is contained in:
Ahmed Nagi 2025-01-20 08:13:07 +00:00
parent c140533954
commit 060f4301e9
8 changed files with 61 additions and 42 deletions

View file

@ -378,6 +378,7 @@ REST_FRAMEWORK = {
"rest_framework.permissions.IsAuthenticated",
),
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
'EXCEPTION_HANDLER': 'utils.exception_handler.custom_exception_handler',
}
REST_AUTH = {
'LOGIN_SERIALIZER': 'lms.accounts.serializers.CustomLoginSerializer',

View file

@ -9,7 +9,7 @@ from django.contrib.auth import get_user_model
from rest_framework.exceptions import ValidationError
from allauth.account.utils import send_email_confirmation
from rest_framework.response import Response
from .validation_error import CustomValidationError
from lms.utils.exception_handler import CustomValidationError
User = get_user_model()

View file

@ -1,24 +0,0 @@
from rest_framework.exceptions import APIException
from rest_framework.response import Response
from rest_framework import status
class CustomSuccessResponse(Response):
def __init__(self, detail=None, code=status.HTTP_200_OK):
data = {"success": True}
if detail is not None:
data["detail"] = detail
super().__init__(data, status=code)
class CustomValidationError(APIException):
status_code = 400
default_detail = 'A validation error occurred.'
default_code = 'validation_error'
def __init__(self, detail=None, code=None):
if detail is not None:
self.detail = detail
if code is not None:
self.status_code = code

View file

@ -7,7 +7,6 @@ from rest_framework.permissions import AllowAny, IsAuthenticated
from .serializers import ChangeEmailSerializer
from asgiref.sync import sync_to_async
from django.contrib.auth import get_user_model
from .validation_error import CustomSuccessResponse, CustomValidationError
User = get_user_model()
@ -17,7 +16,7 @@ class UserView(APIView):
def get(self, request):
user = request.user
image_url = request.build_absolute_uri(user.image.url) if user.image else None
return CustomSuccessResponse({
return Response({
"name": user.full_name,
"image": image_url
})
@ -36,9 +35,9 @@ class UserView(APIView):
print("Ok")
user.save()
return CustomSuccessResponse(
return Response(
{"ok"},
code=status.HTTP_200_OK
status=status.HTTP_200_OK
)

View file

@ -9,15 +9,21 @@ from dj_rest_auth.registration.serializers import RegisterSerializer
class CourseSerializer(serializers.ModelSerializer):
owner_name = serializers.CharField(source='owner.username', read_only=True)
owner_name = serializers.CharField(source='owner.full_name', read_only=True)
owner_image = serializers.SerializerMethodField()
students_in_course = serializers.SerializerMethodField()
class Meta:
model = Course
fields = ['id', 'title', 'description', 'is_paid', 'price', 'image', 'owner_name', 'students_in_course', 'created_at', 'updated_at']
fields = ['id', 'title', 'description', 'is_paid', 'price', 'image', 'owner_name', 'owner_image', 'students_in_course', 'created_at', 'updated_at']
read_only_fields = ['created_at', 'updated_at']
def get_owner_image(self, obj):
request = self.context.get('request')
if obj.owner.image:
return request.build_absolute_uri(obj.owner.image.url)
return None
def get_students_in_course(self, obj):
return Enrollment.objects.filter(course=obj).values('student').distinct().count()

View file

@ -10,7 +10,7 @@ from .permissions import IsOwnerOrReadOnly, IsAdmin
from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied
from django.contrib.auth import get_user_model
from accounts.validation_error import CustomSuccessResponse, CustomValidationError
from lms.utils.exception_handler import CustomValidationError
User = get_user_model()
@ -271,22 +271,22 @@ class EnrollmentViewSet(ModelViewSet):
student = User.objects.filter(email=student_email).first()
if not student:
raise CustomValidationError("User not found", code=status.HTTP_404_NOT_FOUND)
raise CustomValidationError("User not found", status=status.HTTP_404_NOT_FOUND)
if student_email == request.user.email:
raise CustomValidationError("You can't add yourself", code=status.HTTP_400_BAD_REQUEST)
raise CustomValidationError("You can't add yourself", status=status.HTTP_400_BAD_REQUEST)
if Enrollment.objects.filter(student__email=student_email, course=course).exists():
raise CustomValidationError("This user already exists", code=status.HTTP_400_BAD_REQUEST)
raise CustomValidationError("This user already exists", status=status.HTTP_400_BAD_REQUEST)
if not course.is_paid:
raise CustomValidationError("Course is not paid", code=status.HTTP_400_BAD_REQUEST)
raise CustomValidationError("Course is not paid", status=status.HTTP_400_BAD_REQUEST)
# Allow only the course owner to enroll students
if course.owner != request.user:
raise CustomValidationError("You do not have permission to enroll students in this course",
code=status.HTTP_403_FORBIDDEN)
status=status.HTTP_403_FORBIDDEN)
# Validate the data before saving
enrollment_data = {
@ -296,10 +296,10 @@ class EnrollmentViewSet(ModelViewSet):
serializer = PrivateEnrollmentSerializer(data=enrollment_data)
if serializer.is_valid():
serializer.save()
return CustomSuccessResponse(f"Student {student.full_name} has been added",
code=status.HTTP_201_CREATED)
return Response(f"Student {student.full_name} has been added",
status=status.HTTP_201_CREATED)
raise CustomValidationError(serializer.errors, code=status.HTTP_400_BAD_REQUEST)
raise CustomValidationError(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@action(detail=False, methods=['get'], url_path='get-my-students')
def get_my_students(self, request):
@ -314,7 +314,7 @@ class EnrollmentViewSet(ModelViewSet):
.distinct()
)
return CustomSuccessResponse(list(my_students), code=200)
return Response(list(my_students), status=200)

0
lms/utils/__init__.py Normal file
View file

View file

@ -0,0 +1,37 @@
from rest_framework.exceptions import APIException
from rest_framework import status
from rest_framework.views import exception_handler
from rest_framework.response import Response
class CustomValidationError(APIException):
status_code = status.HTTP_400_BAD_REQUEST
default_detail = 'A validation error occurred.'
def __init__(self, detail=None, status=None):
self.detail = detail if detail is not None else self.default_detail
self.status = status if status is not None else self.status
def __str__(self):
return f"{self.detail} (Status: {self.status})"
def custom_exception_handler(exc, context):
# Call REST framework's default exception handler first
response = exception_handler(exc, context)
# Handle CustomValidationError
if isinstance(exc, CustomValidationError):
return Response(
{
'error': exc.detail,
'status_code': exc.status_code,
},
status=exc.status_code,
)
# Return the default response for other exceptions
return response