Index: backend/subjects/serializers.py
===================================================================
--- backend/subjects/serializers.py	(revision 10c6536b0fa848158c1516afea1c8265cb1e1b18)
+++ backend/subjects/serializers.py	(revision e637952bd9f1e6ff1b3d5cd472e5bcc0e0e0d834)
@@ -1,4 +1,4 @@
 from rest_framework import serializers
-from .models import Subject, Subject_Info
+from .models import Subject, Subject_Info, EvaluationMethod, EvaluationComponent, EvaluationReview, OtherReview
 
 class SubjectInfoSerializer(serializers.ModelSerializer):
@@ -29,2 +29,76 @@
             'id', 'name', 'code', 'abstract', 'subject_info'
         ]
+
+class EvaluationComponentSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = EvaluationComponent
+        fields = ['category', 'percentage']
+
+    # def validate(self, data):
+    #     try:
+    #         category = data['category']
+    #         percentage = data['percentage']
+    #         try:
+    #             percentage = int(percentage)
+    #         except ValueError:
+    #             raise ValidationError("percentage should be an integer.")
+    #     except:
+    #         raise ValidationError("invalid data for evaluation component.")
+    #
+    #     return data
+
+
+
+class EvaluationMethodSerializer(serializers.ModelSerializer):
+    components = EvaluationComponentSerializer(many=True)
+
+    class Meta:
+        model = EvaluationMethod
+        fields = ['note', 'components']
+
+    def validate(self, data):
+        total = sum(comp['percentage'] for comp in data['components'])
+        if total != 100:
+            raise serializers.ValidationError("Sum of component percentages must equal 100.")
+        return data
+
+    def create(self, validated_data):
+        components_data = validated_data.pop('components')
+        method = EvaluationMethod.objects.create(**validated_data)
+
+        for comp_data in components_data:
+            EvaluationComponent.objects.create(evaluation_method=method, **comp_data)
+
+        return method
+
+
+class EvaluationReviewSerializer(serializers.ModelSerializer):
+    methods = EvaluationMethodSerializer(many=True)
+
+    class Meta:
+        model = EvaluationReview
+        fields = ['methods']
+
+    def validate(self, data):
+        methods = data.get('methods', [])
+        if len(methods) > 3:
+            raise serializers.ValidationError("A subject can't have more than 3 evaluation methods.")
+        return data
+
+    def create(self, validated_data):
+        methods_data = validated_data.pop('methods')
+        review = self.context['review']
+        evaluation_review = EvaluationReview.objects.create(review=review)
+        for method_data in methods_data:
+            method_data['evaluation_review'] = evaluation_review
+            self.fields['methods'].create(method_data)
+        return evaluation_review
+
+class OtherReviewSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = OtherReview
+        fields = ['category', 'content']
+
+    def create(self, validated_data):
+        review = self.context['review']
+        return OtherReview.objects.create(review=review, **validated_data)
Index: backend/subjects/urls.py
===================================================================
--- backend/subjects/urls.py	(revision 10c6536b0fa848158c1516afea1c8265cb1e1b18)
+++ backend/subjects/urls.py	(revision e637952bd9f1e6ff1b3d5cd472e5bcc0e0e0d834)
@@ -1,5 +1,4 @@
 from django.urls import path
-from .views import ToggleSubjectPreferences, PreferencesView, all_subjects, get_recommendations
-
+from .views import ToggleSubjectPreferences, PreferencesView, all_subjects, get_recommendations, SubjectReview
 urlpatterns = [
     path('all/', all_subjects, name='all_subjects'),
@@ -7,3 +6,4 @@
     path('preferences/', PreferencesView.as_view(), name='student-preferences'),
     path('toggle-subject-pref/', ToggleSubjectPreferences.as_view(), name='student-toggle-preferences'),
+    path('subject-review', SubjectReview.as_view(), name='subject-review')
 ]
Index: backend/subjects/views.py
===================================================================
--- backend/subjects/views.py	(revision 10c6536b0fa848158c1516afea1c8265cb1e1b18)
+++ backend/subjects/views.py	(revision e637952bd9f1e6ff1b3d5cd472e5bcc0e0e0d834)
@@ -9,6 +9,6 @@
 from django.db.models import Case, When
 from subjects.utils import get_eligible_subjects, get_recommendations_cache_key, get_recommended_subjects, map_to_subjects_vector, score_for_preferences, get_student_vector
-from .serializers import SubjectSerializer
-from .models import Subject
+from .serializers import SubjectSerializer, EvaluationReviewSerializer, OtherReviewSerializer
+from .models import Subject, Review, EvaluationReview
 
 def index(request):
@@ -88,7 +88,4 @@
             subject = Subject.objects.get(id=subject_id)
 
-            if action_type not in ['favorite', 'liked', 'disliked']:
-                return Response({"message": "Invalid action type. Use 'favorite', 'liked', or 'disliked'."}, status=status.HTTP_400_BAD_REQUEST)
-            
             if action_type == 'favorite':
                 if subject in student.favorite_subjects.all():
@@ -112,4 +109,7 @@
                     student.disliked_subjects.add(subject)
                     action = 'added'
+            else:
+                return Response({"message": "Invalid action type. Use 'favorite', 'liked', or 'disliked'."},
+                                status=status.HTTP_400_BAD_REQUEST)
                 
             return Response({
@@ -125,2 +125,66 @@
         except Exception as e:
             return Response({'error': f'An unexpected error occurred: {str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
+
+class SubjectReview(APIView):
+    permission_classes = [IsAuthenticated]
+
+    def post(self, request):
+        student = request.user.student
+        subject_id = request.data.get('subject_id')
+        review_type = request.data.get('type')
+
+        if not subject_id or review_type not in ['evaluation', 'other']:
+            return Response({'error': 'Missing or invalid data.'}, status=status.HTTP_400_BAD_REQUEST)
+        try:
+            subject_id = int(subject_id)
+        except (TypeError, ValueError):
+            return Response({'error': 'Invalid subject ID.'}, status=status.HTTP_400_BAD_REQUEST)
+
+        try:
+            subject = Subject.objects.get(pk=subject_id)
+        except Subject.DoesNotExist:
+            return Response({'error': 'Subject not found.'}, status=status.HTTP_404_NOT_FOUND)
+
+        existing = Review.objects.filter(
+            student=student,
+            subject_id=subject_id,
+            review_type=review_type
+        ).exists()
+
+        if existing:
+            return Response(
+                {"error": "You have already submitted this type of review for this subject."},
+                status=status.HTTP_400_BAD_REQUEST
+            )
+
+        existing_evaluation = EvaluationReview.objects.filter(
+            review__subject_id=subject_id
+        ).exists()
+
+        if existing_evaluation:
+            return Response(
+                {"error": "An evaluation review for this subject already exists."},
+                status=status.HTTP_400_BAD_REQUEST
+            )
+
+        review = Review.objects.create(
+            student=student,
+            subject=subject,
+            review_type=review_type
+        )
+
+        if review_type == "evaluation":
+            serializer = EvaluationReviewSerializer(data=request.data, context={'review': review})
+        else:
+            serializer = OtherReviewSerializer(data=request.data, context={'review': review})
+
+        if serializer.is_valid():
+            serializer.save()
+            return Response({
+                    "message": f"{review_type.capitalize()} review created.",
+                    "review_id": review.id,
+                    },
+                status=status.HTTP_201_CREATED)
+        else:
+            review.delete()
+            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
