Skip to content

Commit f047b3c

Browse files
authored
Revert "Advanced search filter backend routes (#744)" (#759)
This reverts commit aaaa13a.
1 parent 54ae238 commit f047b3c

File tree

20 files changed

+1319
-1132
lines changed

20 files changed

+1319
-1132
lines changed

backend/courses/filters.py

Lines changed: 445 additions & 172 deletions
Large diffs are not rendered by default.

backend/courses/migrations/0067_alter_meeting_associated_break_and_more.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@ class Migration(migrations.Migration):
2727
model_name="meeting",
2828
constraint=models.UniqueConstraint(
2929
condition=models.Q(
30-
("section__isnull", True),
31-
("associated_break__isnull", True),
32-
_connector="OR",
30+
("section__isnull", True), ("associated_break__isnull", True), _connector="OR"
3331
),
3432
fields=("section", "associated_break"),
3533
name="unique_meeting_either_section_or_break",
@@ -39,9 +37,7 @@ class Migration(migrations.Migration):
3937
model_name="meeting",
4038
constraint=models.UniqueConstraint(
4139
condition=models.Q(
42-
("section__isnull", True),
43-
("associated_break__isnull", True),
44-
_negated=True,
40+
("section__isnull", True), ("associated_break__isnull", True), _negated=True
4541
),
4642
fields=("section", "associated_break"),
4743
name="meeting_must_have_section_or_break",

backend/courses/serializers.py

Lines changed: 0 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from decimal import Decimal
21
from textwrap import dedent
32

43
from django.contrib.auth import get_user_model
@@ -518,91 +517,3 @@ class FriendshipRequestSerializer(serializers.Serializer):
518517

519518
def to_representation(self, instance):
520519
return super().to_representation(instance)
521-
522-
523-
class AdvancedSearchEnumSerializer(serializers.Serializer):
524-
type = serializers.ChoiceField(choices=["enum"])
525-
field = serializers.CharField()
526-
op = serializers.ChoiceField(choices=["is", "is_not", "is_any_of", "is_none_of"])
527-
value = serializers.ListField(
528-
child=serializers.CharField(),
529-
allow_empty=True,
530-
)
531-
532-
533-
class AdvancedSearchNumericSerializer(serializers.Serializer):
534-
type = serializers.ChoiceField(choices=["numeric"])
535-
field = serializers.CharField()
536-
op = serializers.ChoiceField(choices=["lt", "lte", "gt", "gte", "eq", "neq"])
537-
value = serializers.DecimalField(max_digits=4, decimal_places=2)
538-
539-
540-
class AdvancedSearchStartTimeSerializer(AdvancedSearchNumericSerializer):
541-
field = serializers.ChoiceField(choices=["start_time"])
542-
value = serializers.DecimalField(
543-
min_value=Decimal(0.0), max_value=Decimal(23.99), max_digits=4, decimal_places=2
544-
)
545-
546-
547-
class AdvancedSearchBooleanSerializer(serializers.Serializer):
548-
type = serializers.ChoiceField(choices=["boolean"])
549-
field = serializers.CharField()
550-
value = serializers.BooleanField()
551-
552-
553-
class AdvancedSearchValueSerializer(serializers.Serializer):
554-
type = serializers.ChoiceField(choices=["value"])
555-
field = serializers.CharField()
556-
value = serializers.Field()
557-
558-
559-
class AdvancedSearchConditionSerializer(serializers.Serializer):
560-
def to_internal_value(self, data):
561-
field_map = {
562-
"days": AdvancedSearchEnumSerializer,
563-
"activity": AdvancedSearchEnumSerializer,
564-
"cu": AdvancedSearchEnumSerializer,
565-
"start_time": AdvancedSearchNumericSerializer,
566-
"end_time": AdvancedSearchNumericSerializer,
567-
"difficulty": AdvancedSearchNumericSerializer,
568-
"course_quality": AdvancedSearchNumericSerializer,
569-
"instructor_quality": AdvancedSearchNumericSerializer,
570-
"is_open": AdvancedSearchBooleanSerializer,
571-
"fit_schedule": AdvancedSearchValueSerializer,
572-
}
573-
serializer_class = field_map.get(data.get("field"))
574-
if serializer_class is None:
575-
raise serializers.ValidationError({"type": "Invalid type"})
576-
577-
serializer = serializer_class(data=data)
578-
serializer.is_valid(raise_exception=True)
579-
return serializer.validated_data
580-
581-
582-
class AdvancedSearchGroupSerializer(serializers.Serializer):
583-
type = serializers.ChoiceField(choices=["group"])
584-
op = serializers.ChoiceField(choices=["AND", "OR"])
585-
children = serializers.ListField(
586-
child=AdvancedSearchConditionSerializer(),
587-
allow_empty=False,
588-
max_length=5,
589-
)
590-
591-
592-
class AdvancedSearchDataSerializer(serializers.Serializer):
593-
op = serializers.ChoiceField(choices=["AND", "OR"])
594-
children = serializers.ListField(
595-
max_length=10,
596-
allow_empty=True,
597-
)
598-
599-
def validate_children(self, children):
600-
validated_children = []
601-
for f in children:
602-
if f.get("type") == "group":
603-
serializer = AdvancedSearchGroupSerializer(data=f)
604-
else:
605-
serializer = AdvancedSearchConditionSerializer(data=f)
606-
serializer.is_valid(raise_exception=True)
607-
validated_children.append(serializer.validated_data)
608-
return validated_children

backend/courses/urls.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
from django.urls import path
22

33
from courses import views
4+
from courses.views import CourseListSearch, Health
45

56

67
urlpatterns = [
7-
path("health/", views.Health.as_view(), name="health"),
8+
path("health/", Health.as_view(), name="health"),
89
path("<slug:semester>/courses/", views.CourseList.as_view(), name="courses-list"),
910
path(
1011
"<slug:semester>/search/courses/",
11-
views.CourseListSearch.as_view(),
12+
CourseListSearch.as_view(),
1213
name="courses-search",
1314
),
1415
path(

backend/courses/views.py

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from rest_framework.response import Response
1212
from rest_framework.views import APIView
1313

14-
from courses.filters import CourseSearchAdvancedFilterBackend
14+
from courses.filters import CourseSearchFilterBackend
1515
from courses.models import (
1616
Attribute,
1717
Course,
@@ -175,19 +175,14 @@ def get_queryset(self):
175175
class CourseListSearch(CourseList):
176176
"""
177177
This route allows you to list courses by certain search terms and/or filters.
178-
- **GET**: (Deprecated) Without any GET parameters, this route simply returns all courses
178+
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.
191186
"""
192187

193188
schema = PcxAutoSchema(
@@ -196,18 +191,11 @@ class CourseListSearch(CourseList):
196191
"GET": {
197192
200: "[DESCRIBE_RESPONSE_SCHEMA]Courses listed successfully.",
198193
400: "Bad request (invalid query).",
199-
},
200-
"POST": {
201-
200: "[DESCRIBE_RESPONSE_SCHEMA]Courses listed successfully.",
202-
400: "Bad request (invalid query).",
203-
},
194+
}
204195
}
205196
},
206197
custom_path_parameter_desc={
207-
"courses-search": {
208-
"GET": {"semester": SEMESTER_PARAM_DESCRIPTION},
209-
"POST": {"semester": SEMESTER_PARAM_DESCRIPTION},
210-
}
198+
"courses-search": {"GET": {"semester": SEMESTER_PARAM_DESCRIPTION}}
211199
},
212200
)
213201

@@ -233,12 +221,7 @@ def get_serializer_context(self):
233221
if self.request is None or not self.request.user or not self.request.user.is_authenticated:
234222
return context
235223

236-
(
237-
_,
238-
_,
239-
curr_course_vectors_dict,
240-
past_course_vectors_dict,
241-
) = retrieve_course_clusters()
224+
_, _, curr_course_vectors_dict, past_course_vectors_dict = retrieve_course_clusters()
242225
user_vector, _ = vectorize_user(
243226
self.request.user, curr_course_vectors_dict, past_course_vectors_dict
244227
)
@@ -251,23 +234,9 @@ def get_serializer_context(self):
251234

252235
return context
253236

237+
filter_backends = [TypedCourseSearchBackend, CourseSearchFilterBackend]
254238
search_fields = ("full_code", "title", "sections__instructors__name")
255239

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-
271240

272241
class CourseDetail(generics.RetrieveAPIView, BaseCourseMixin):
273242
"""

backend/plan/migrations/0010_break.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ class Migration(migrations.Migration):
1919
(
2020
"id",
2121
models.AutoField(
22-
auto_created=True,
23-
primary_key=True,
24-
serialize=False,
25-
verbose_name="ID",
22+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
2623
),
2724
),
2825
(

backend/plan/migrations/0014_break_unique_break_meeting_times_per_person.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ class Migration(migrations.Migration):
1616
model_name="break",
1717
constraint=models.UniqueConstraint(
1818
condition=models.Q(
19-
("meeting_times__isnull", False),
20-
models.Q(("meeting_times", ""), _negated=True),
19+
("meeting_times__isnull", False), models.Q(("meeting_times", ""), _negated=True)
2120
),
2221
fields=("person", "meeting_times"),
2322
name="unique_break_meeting_times_per_person",

backend/plan/serializers.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,7 @@ class ScheduleSerializer(serializers.ModelSerializer):
4848
required=True,
4949
)
5050
breaks = BreakSerializer(
51-
many=True,
52-
read_only=False,
53-
help_text="The breaks in the schedule.",
54-
required=False,
51+
many=True, read_only=False, help_text="The breaks in the schedule.", required=False
5552
)
5653
id = serializers.IntegerField(
5754
read_only=False, required=False, help_text="The id of the schedule."

backend/plan/util.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33

44
def get_first_matching_date(start_date_str, days):
5-
day_map = {"MO": 0, "TU": 1, "WE": 2, "TH": 3, "FR": 4, "SA": 5, "SU": 6}
6-
start_date = datetime.datetime.strptime(start_date_str, "%Y-%m-%d").date()
5+
day_map = {"MO": 0, "TU": 1, "WE": 2,
6+
"TH": 3, "FR": 4, "SA": 5, "SU": 6}
7+
start_date = datetime.datetime.strptime(
8+
start_date_str, "%Y-%m-%d").date()
79
weekdays = [day_map[code] for code in days]
810

911
for i in range(7):

0 commit comments

Comments
 (0)