u
This commit is contained in:
parent
c140533954
commit
060f4301e9
8 changed files with 61 additions and 42 deletions
|
|
@ -378,6 +378,7 @@ REST_FRAMEWORK = {
|
||||||
"rest_framework.permissions.IsAuthenticated",
|
"rest_framework.permissions.IsAuthenticated",
|
||||||
),
|
),
|
||||||
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
|
"DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
|
||||||
|
'EXCEPTION_HANDLER': 'utils.exception_handler.custom_exception_handler',
|
||||||
}
|
}
|
||||||
REST_AUTH = {
|
REST_AUTH = {
|
||||||
'LOGIN_SERIALIZER': 'lms.accounts.serializers.CustomLoginSerializer',
|
'LOGIN_SERIALIZER': 'lms.accounts.serializers.CustomLoginSerializer',
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ from django.contrib.auth import get_user_model
|
||||||
from rest_framework.exceptions import ValidationError
|
from rest_framework.exceptions import ValidationError
|
||||||
from allauth.account.utils import send_email_confirmation
|
from allauth.account.utils import send_email_confirmation
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from .validation_error import CustomValidationError
|
from lms.utils.exception_handler import CustomValidationError
|
||||||
|
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
|
|
@ -7,7 +7,6 @@ from rest_framework.permissions import AllowAny, IsAuthenticated
|
||||||
from .serializers import ChangeEmailSerializer
|
from .serializers import ChangeEmailSerializer
|
||||||
from asgiref.sync import sync_to_async
|
from asgiref.sync import sync_to_async
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
from .validation_error import CustomSuccessResponse, CustomValidationError
|
|
||||||
|
|
||||||
User = get_user_model()
|
User = get_user_model()
|
||||||
|
|
||||||
|
|
@ -17,7 +16,7 @@ class UserView(APIView):
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
user = request.user
|
user = request.user
|
||||||
image_url = request.build_absolute_uri(user.image.url) if user.image else None
|
image_url = request.build_absolute_uri(user.image.url) if user.image else None
|
||||||
return CustomSuccessResponse({
|
return Response({
|
||||||
"name": user.full_name,
|
"name": user.full_name,
|
||||||
"image": image_url
|
"image": image_url
|
||||||
})
|
})
|
||||||
|
|
@ -36,9 +35,9 @@ class UserView(APIView):
|
||||||
print("Ok")
|
print("Ok")
|
||||||
user.save()
|
user.save()
|
||||||
|
|
||||||
return CustomSuccessResponse(
|
return Response(
|
||||||
{"ok"},
|
{"ok"},
|
||||||
code=status.HTTP_200_OK
|
status=status.HTTP_200_OK
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,21 @@ from dj_rest_auth.registration.serializers import RegisterSerializer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class CourseSerializer(serializers.ModelSerializer):
|
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()
|
students_in_course = serializers.SerializerMethodField()
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Course
|
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']
|
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):
|
def get_students_in_course(self, obj):
|
||||||
return Enrollment.objects.filter(course=obj).values('student').distinct().count()
|
return Enrollment.objects.filter(course=obj).values('student').distinct().count()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ from .permissions import IsOwnerOrReadOnly, IsAdmin
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.exceptions import PermissionDenied
|
from rest_framework.exceptions import PermissionDenied
|
||||||
from django.contrib.auth import get_user_model
|
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()
|
User = get_user_model()
|
||||||
|
|
@ -271,22 +271,22 @@ class EnrollmentViewSet(ModelViewSet):
|
||||||
student = User.objects.filter(email=student_email).first()
|
student = User.objects.filter(email=student_email).first()
|
||||||
|
|
||||||
if not student:
|
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:
|
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():
|
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:
|
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
|
# Allow only the course owner to enroll students
|
||||||
if course.owner != request.user:
|
if course.owner != request.user:
|
||||||
raise CustomValidationError("You do not have permission to enroll students in this course",
|
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
|
# Validate the data before saving
|
||||||
enrollment_data = {
|
enrollment_data = {
|
||||||
|
|
@ -296,10 +296,10 @@ class EnrollmentViewSet(ModelViewSet):
|
||||||
serializer = PrivateEnrollmentSerializer(data=enrollment_data)
|
serializer = PrivateEnrollmentSerializer(data=enrollment_data)
|
||||||
if serializer.is_valid():
|
if serializer.is_valid():
|
||||||
serializer.save()
|
serializer.save()
|
||||||
return CustomSuccessResponse(f"Student {student.full_name} has been added",
|
return Response(f"Student {student.full_name} has been added",
|
||||||
code=status.HTTP_201_CREATED)
|
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')
|
@action(detail=False, methods=['get'], url_path='get-my-students')
|
||||||
def get_my_students(self, request):
|
def get_my_students(self, request):
|
||||||
|
|
@ -314,7 +314,7 @@ class EnrollmentViewSet(ModelViewSet):
|
||||||
.distinct()
|
.distinct()
|
||||||
)
|
)
|
||||||
|
|
||||||
return CustomSuccessResponse(list(my_students), code=200)
|
return Response(list(my_students), status=200)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
0
lms/utils/__init__.py
Normal file
0
lms/utils/__init__.py
Normal file
37
lms/utils/exception_handler.py
Normal file
37
lms/utils/exception_handler.py
Normal 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
|
||||||
Loading…
Add table
Reference in a new issue