1111from rest_framework .response import Response
1212from rest_framework .views import APIView
1313
14- from courses .filters import CourseSearchFilterBackend
14+ from courses .filters import CourseSearchAdvancedFilterBackend
1515from courses .models import (
1616 Attribute ,
1717 Course ,
@@ -175,14 +175,19 @@ def get_queryset(self):
175175class CourseListSearch (CourseList ):
176176 """
177177 This route allows you to list courses by certain search terms and/or filters.
178- Without any GET parameters, this route simply returns all courses
178+ - **GET**: (Deprecated) Without any GET parameters, this route simply returns all courses
179179 for a given semester. There are a few filter query parameters which constitute ranges of
180180 floating-point numbers. The values for these are <min>-<max> , with minimum excluded.
181181 For example, looking for classes in the range of 0-2.5 in difficulty, you would add the
182182 parameter difficulty=0-2.5. If you are a backend developer, you can find these filters in
183183 backend/plan/filters.py/CourseSearchFilterBackend. If you are reading the frontend docs,
184184 these filters are listed below in the query parameters list (with description starting with
185185 "Filter").
186+ - **POST**: This route also accepts POST requests, where the body is a JSON object
187+ containing a "filters" key, which maps to an object containing the same filters as
188+ described above. This API will allow for a more extensible filtering system.
189+ If you are a backend or frontenddeveloper, you can find these filters and request
190+ body schema in backend/plan/filters.py/CourseSearchAdvancedFilterBackend.
186191 """
187192
188193 schema = PcxAutoSchema (
@@ -191,11 +196,18 @@ class CourseListSearch(CourseList):
191196 "GET" : {
192197 200 : "[DESCRIBE_RESPONSE_SCHEMA]Courses listed successfully." ,
193198 400 : "Bad request (invalid query)." ,
194- }
199+ },
200+ "POST" : {
201+ 200 : "[DESCRIBE_RESPONSE_SCHEMA]Courses listed successfully." ,
202+ 400 : "Bad request (invalid query)." ,
203+ },
195204 }
196205 },
197206 custom_path_parameter_desc = {
198- "courses-search" : {"GET" : {"semester" : SEMESTER_PARAM_DESCRIPTION }}
207+ "courses-search" : {
208+ "GET" : {"semester" : SEMESTER_PARAM_DESCRIPTION },
209+ "POST" : {"semester" : SEMESTER_PARAM_DESCRIPTION },
210+ }
199211 },
200212 )
201213
@@ -221,7 +233,12 @@ def get_serializer_context(self):
221233 if self .request is None or not self .request .user or not self .request .user .is_authenticated :
222234 return context
223235
224- _ , _ , curr_course_vectors_dict , past_course_vectors_dict = retrieve_course_clusters ()
236+ (
237+ _ ,
238+ _ ,
239+ curr_course_vectors_dict ,
240+ past_course_vectors_dict ,
241+ ) = retrieve_course_clusters ()
225242 user_vector , _ = vectorize_user (
226243 self .request .user , curr_course_vectors_dict , past_course_vectors_dict
227244 )
@@ -234,9 +251,23 @@ def get_serializer_context(self):
234251
235252 return context
236253
237- filter_backends = [TypedCourseSearchBackend , CourseSearchFilterBackend ]
238254 search_fields = ("full_code" , "title" , "sections__instructors__name" )
239255
256+ def get (self , request , * args , ** kwargs ):
257+ queryset = super ().get_queryset ()
258+ queryset = TypedCourseSearchBackend ().filter_queryset (request , queryset , self )
259+
260+ serializer = self .get_serializer (queryset , many = True )
261+ return Response (serializer .data )
262+
263+ def post (self , request , * args , ** kwargs ):
264+ queryset = super ().get_queryset ()
265+ queryset = TypedCourseSearchBackend ().filter_queryset (request , queryset , self )
266+ queryset = CourseSearchAdvancedFilterBackend ().filter_queryset (request , queryset , self )
267+
268+ serializer = self .get_serializer (queryset , many = True )
269+ return Response (serializer .data )
270+
240271
241272class CourseDetail (generics .RetrieveAPIView , BaseCourseMixin ):
242273 """
0 commit comments