From 7bf1cb4e298bdede7323237688de6a10c1912f82 Mon Sep 17 00:00:00 2001 From: Muhammad Haseeb Date: Sat, 5 Jun 2021 14:52:55 +0500 Subject: [PATCH] Cleaned up unused code to move closer to open edX codebase EDLY-2704 (#37) --- course_discovery/apps/api/serializers.py | 23 +++---- .../apps/api/tests/test_serializers.py | 63 ------------------- course_discovery/apps/api/tests/test_utils.py | 31 +-------- course_discovery/apps/api/utils.py | 15 ----- .../v1/tests/test_views/test_course_runs.py | 55 ---------------- .../api/v1/tests/test_views/test_courses.py | 19 ------ .../api/v1/tests/test_views/test_programs.py | 19 ------ .../apps/api/v1/views/course_runs.py | 21 +------ course_discovery/apps/api/v1/views/courses.py | 8 --- .../apps/api/v1/views/programs.py | 9 +-- .../apps/course_metadata/search_indexes.py | 2 +- 11 files changed, 13 insertions(+), 252 deletions(-) diff --git a/course_discovery/apps/api/serializers.py b/course_discovery/apps/api/serializers.py index 535b44e5ae..776ed51f32 100644 --- a/course_discovery/apps/api/serializers.py +++ b/course_discovery/apps/api/serializers.py @@ -27,7 +27,7 @@ from course_discovery.apps.api.fields import ( HtmlField, ImageField, SlugRelatedFieldWithReadSerializer, SlugRelatedTranslatableField, StdImageSerializerField ) -from course_discovery.apps.api.utils import StudioAPI, get_queryset_filtered_on_organization +from course_discovery.apps.api.utils import StudioAPI from course_discovery.apps.catalogs.models import Catalog from course_discovery.apps.core.api_client.lms import LMSAPIClient from course_discovery.apps.course_metadata import search_indexes @@ -779,7 +779,7 @@ class Meta: model = CourseRun fields = ('key', 'uuid', 'title', 'external_key', 'image', 'short_description', 'marketing_url', 'seats', 'start', 'end', 'go_live_date', 'enrollment_start', 'enrollment_end', - 'pacing_type', 'type', 'run_type', 'status', 'is_enrollable', 'is_marketable', 'term',) + 'pacing_type', 'type', 'run_type', 'status', 'is_enrollable', 'is_marketable', 'term', 'subjects',) def get_marketing_url(self, obj): include_archived = self.context.get('include_archived') @@ -944,10 +944,8 @@ class CourseRunWithProgramsSerializer(CourseRunSerializer): programs = serializers.SerializerMethodField() @classmethod - def prefetch_queryset(cls, queryset=None, edx_org_short_name=None): - edx_org_filter = 'course__authoring_organizations__key' + def prefetch_queryset(cls, queryset=None): queryset = super().prefetch_queryset(queryset=queryset) - queryset = get_queryset_filtered_on_organization(queryset, edx_org_filter, edx_org_short_name) return queryset.prefetch_related('course__programs__excluded_course_runs') @@ -1128,15 +1126,12 @@ class CourseWithProgramsSerializer(CourseSerializer): editable = serializers.SerializerMethodField() @classmethod - def prefetch_queryset(cls, partner, edx_org_short_name=None, queryset=None, course_runs=None, programs=None): + def prefetch_queryset(cls, partner, queryset=None, course_runs=None, programs=None): # pylint: disable=arguments-differ """ Similar to the CourseSerializer's prefetch_queryset, but prefetches a filtered CourseRun queryset. """ - edx_org_filter = 'authoring_organizations__key' queryset = queryset if queryset is not None else Course.objects.filter(partner=partner) - - queryset = get_queryset_filtered_on_organization(queryset, edx_org_filter, edx_org_short_name) return queryset.select_related( 'level_type', 'video', @@ -1150,7 +1145,7 @@ def prefetch_queryset(cls, partner, edx_org_short_name=None, queryset=None, cour 'prerequisites', 'topics', 'url_slug_history', - Prefetch('subjects', queryset=SubjectSerializer.prefetch_queryset()), + Prefetch('subjects', queryset=SubjectSerializer.prefetch_queryset(partner)), Prefetch('course_runs', queryset=CourseRunSerializer.prefetch_queryset(queryset=course_runs)), Prefetch('authoring_organizations', queryset=OrganizationSerializer.prefetch_queryset(partner)), Prefetch('sponsoring_organizations', queryset=OrganizationSerializer.prefetch_queryset(partner)), @@ -1436,11 +1431,9 @@ class MinimalProgramSerializer(DynamicFieldsMixin, BaseModelSerializer): curricula = CurriculumSerializer(many=True) @classmethod - def prefetch_queryset(cls, partner, queryset=None, edx_org_short_name=None): + def prefetch_queryset(cls, partner, queryset=None): # Explicitly check if the queryset is None before selecting related - edx_org_filter = 'authoring_organizations__key' queryset = queryset if queryset is not None else Program.objects.filter(partner=partner) - queryset = get_queryset_filtered_on_organization(queryset, edx_org_filter, edx_org_short_name) return queryset.select_related('type', 'partner').prefetch_related( 'excluded_course_runs', @@ -1577,7 +1570,7 @@ class ProgramSerializer(MinimalProgramSerializer): curricula = CurriculumSerializer(many=True, required=False) @classmethod - def prefetch_queryset(cls, partner, queryset=None, edx_org_short_name=None): + def prefetch_queryset(cls, partner, queryset=None): """ Prefetch the related objects that will be serialized with a `Program`. @@ -1585,9 +1578,7 @@ def prefetch_queryset(cls, partner, queryset=None, edx_org_short_name=None): chain of related fields from programs to course runs (i.e., we want control over the querysets that we're prefetching). """ - edx_org_filter = 'authoring_organizations__key' queryset = queryset if queryset is not None else Program.objects.filter(partner=partner) - queryset = get_queryset_filtered_on_organization(queryset, edx_org_filter, edx_org_short_name) return queryset.select_related('type', 'video', 'partner').prefetch_related( 'excluded_course_runs', diff --git a/course_discovery/apps/api/tests/test_serializers.py b/course_discovery/apps/api/tests/test_serializers.py index 69431eaa01..b089bfae7c 100644 --- a/course_discovery/apps/api/tests/test_serializers.py +++ b/course_discovery/apps/api/tests/test_serializers.py @@ -468,18 +468,6 @@ def test_advertise_course_run_else_condition(self): serializer = self.serializer_class(self.course, context={'request': self.request}) self.assertEqual(serializer.data['advertised_course_run_uuid'], expected_advertised_course_run.uuid) - def test_filter_courses_on_edx_org_short_name(self): - """ - Verify courses filtering on edX organization works as expected.. - """ - edx_org_short_name = 'edx' - edx_org_course = CourseFactory(partner=self.partner, authoring_organizations__key=edx_org_short_name) - serialized_courses = self.serializer_class.prefetch_queryset( - partner=self.partner, - edx_org_short_name=edx_org_short_name - ) - assert serialized_courses.values() != self.get_expected_data(edx_org_course, self.request).values() - class CurriculumSerializerTests(TestCase): serializer_class = CurriculumSerializer @@ -743,17 +731,6 @@ def test_include_retired_programs(self): NestedProgramSerializer([retired_program], many=True, context=self.serializer_context).data ) - def test_filter_course_runs_on_edx_org_short_name(self): - """ - Verify course runs filtering on edX organization works as expected. - """ - edx_org_short_name = 'edx' - edx_org_course = CourseRunFactory(course__authoring_organizations__key=edx_org_short_name) - serialized_course_runs = CourseRunWithProgramsSerializer.prefetch_queryset( - edx_org_short_name=edx_org_short_name - ) - assert serialized_course_runs.values() != self.get_expected_data(edx_org_course, self.request).values() - @classmethod def get_expected_data(cls, course_run, request): expected = CourseRunSerializer(course_run, context={'request': request}).data @@ -1039,16 +1016,6 @@ def test_data(self): expected = self.get_expected_data(program, request) self.assertDictEqual(serializer.data, expected) - def test_filter_programs_on_edx_org_short_name(self): - """ - Verify programs filtering on edX organization works as expected. - """ - edx_org_short_name = 'edx' - request = make_request() - edx_org_program = ProgramFactory(authoring_organizations__key=edx_org_short_name) - serializer = self.serializer_class(edx_org_program, context={'request': request}) - assert serializer.data['title'] == self.get_expected_data(edx_org_program, request)['title'] - class ProgramSerializerTests(MinimalProgramSerializerTests): serializer_class = ProgramSerializer @@ -1345,16 +1312,6 @@ def test_degree_marketing_data(self): } self.assertDictEqual(serializer.data, expected) - def test_filter_programs_on_edx_org_short_name(self): - """ - Verify programs filtering on edX organization works as expected. - """ - edx_org_short_name = 'edx' - request = make_request() - edx_org_program = ProgramFactory(authoring_organizations__key=edx_org_short_name) - serializer = self.serializer_class(edx_org_program, context={'request': request}) - assert serializer.data['title'] == self.get_expected_data(edx_org_program, request)['title'] - class PathwaySerialzerTests(TestCase): def test_data(self): @@ -1402,7 +1359,6 @@ def test_data(self): class ContainedCourseRunsSerializerTests(TestCase): - def test_data(self): instance = { 'course_runs': { @@ -1413,25 +1369,6 @@ def test_data(self): serializer = ContainedCourseRunsSerializer(instance) self.assertDictEqual(serializer.data, instance) - def test_contained_course_runs_filtered_on_edx_org_short_name(self): - """ - Verify course runs keys filtering on elastic search query string & edX organization. - """ - edx_org_short_name = 'edx' - edx_org_course_run_key = 'course-v1:edX+DemoX+Demo_Course' - course_run_ids = [edx_org_course_run_key] - course_runs_with_org_filter = CourseRun.objects.filter(course__authoring_organizations__key=edx_org_short_name) - course_runs_keys = course_runs_with_org_filter.values_list('key', flat=True) - contained_course_runs = {course_run_id: course_run_id in course_runs_keys for course_run_id in course_run_ids} - course_runs_instances = {'course_runs': contained_course_runs} - contained_course_runs_serializer = ContainedCourseRunsSerializer(course_runs_instances) - expected_contained_courses = { - 'course_runs': { - edx_org_course_run_key: False - } - } - assert contained_course_runs_serializer.data == expected_contained_courses - class ContainedCoursesSerializerTests(TestCase): def test_data(self): diff --git a/course_discovery/apps/api/tests/test_utils.py b/course_discovery/apps/api/tests/test_utils.py index 1e60acc566..f7f4a9fbc1 100644 --- a/course_discovery/apps/api/tests/test_utils.py +++ b/course_discovery/apps/api/tests/test_utils.py @@ -3,15 +3,13 @@ import ddt import mock -import pytest from django.test import TestCase from opaque_keys.edx.keys import CourseKey from rest_framework.request import Request from rest_framework.test import APIRequestFactory -from course_discovery.apps.api.utils import StudioAPI, cast2int, get_query_param, get_queryset_filtered_on_organization +from course_discovery.apps.api.utils import StudioAPI, cast2int, get_query_param from course_discovery.apps.core.utils import serialize_datetime -from course_discovery.apps.course_metadata.models import Course, CourseRun from course_discovery.apps.course_metadata.tests.factories import CourseEditorFactory, CourseRunFactory LOGGER_PATH = 'course_discovery.apps.api.utils.logger.exception' @@ -50,33 +48,6 @@ def test_without_request(self): assert get_query_param(None, 'q') is None -class TestGetQuerysetFilteredOnOrganization: - - @pytest.mark.django_db - def test_courses_runs_filter_on_edx_shortname(self): - edx_org_filter = 'course__authoring_organizations__key' - edx_org_short_name = 'edx' - edx_course_run_key = 'course-v1:edX+DemoX+Demo_Course' - expected_course_runs_queryset = CourseRun.objects.filter(course__authoring_organizations__key=edx_org_short_name) - - course_runs_queryset = CourseRun.objects.filter(key=edx_course_run_key) - actual_course_runs_queryset = get_queryset_filtered_on_organization(course_runs_queryset, edx_org_filter, edx_org_short_name) - - assert len(actual_course_runs_queryset) == len(expected_course_runs_queryset) - - @pytest.mark.django_db - def test_course_filter_on_edx_shortname(self): - edx_org_filter = 'authoring_organizations__key' - edx_org_short_name = 'edx' - edx_course_key = 'course-v1:edX+DemoX+Demo_Course' - expected_courses_queryset = Course.objects.filter(authoring_organizations__key=edx_org_short_name) - - courses_queryset = Course.objects.filter(key=edx_course_key) - actual_courses_queryset = get_queryset_filtered_on_organization(courses_queryset, edx_org_filter, edx_org_short_name) - - assert len(actual_courses_queryset) == len(expected_courses_queryset) - - @ddt.ddt class StudioAPITests(TestCase): def setUp(self): diff --git a/course_discovery/apps/api/utils.py b/course_discovery/apps/api/utils.py index 2a37e39fa3..a9fc384835 100644 --- a/course_discovery/apps/api/utils.py +++ b/course_discovery/apps/api/utils.py @@ -208,18 +208,3 @@ def push_to_studio(self, course_run, create=False, old_course_run_key=None, user response = self.update_course_run_details_in_studio(course_run) return response - - -def get_queryset_filtered_on_organization(queryset, edx_org_filter, edx_org_short_name): - """ - Get queryset filtered on edx organization short name. - - Arguments: - queryset (DRF queryset object): DRF Queryset object. - edx_org_filter (str): Filter to use in queryset. - edx_org_short_name (str): Edx organization short name. - - Returns: - A DRF queryset object with organization filter applied. - """ - return queryset if not edx_org_short_name else queryset.filter(**{edx_org_filter: edx_org_short_name}) diff --git a/course_discovery/apps/api/v1/tests/test_views/test_course_runs.py b/course_discovery/apps/api/v1/tests/test_views/test_course_runs.py index a72c2d9d7a..b3762c958f 100644 --- a/course_discovery/apps/api/v1/tests/test_views/test_course_runs.py +++ b/course_discovery/apps/api/v1/tests/test_views/test_course_runs.py @@ -31,15 +31,9 @@ class CourseRunViewSetTests(SerializationMixin, ElasticsearchTestMixin, OAuth2Mi def setUp(self): super(CourseRunViewSetTests, self).setUp() self.user = UserFactory(is_staff=True) - self.edx_org_short_name = 'edx' self.client.force_authenticate(self.user) self.course_run = CourseRunFactory(course__partner=self.partner) self.course_run_2 = CourseRunFactory(course__key='Test+Course', course__partner=self.partner) - # Course_run of edx organization - self.course_run_3 = CourseRunFactory( - course__partner=self.partner, - course__authoring_organizations__key=self.edx_org_short_name - ) self.draft_course = CourseFactory(partner=self.partner, draft=True) self.draft_course_run = CourseRunFactory(course=self.draft_course, draft=True) self.draft_course_run.course.authoring_organizations.add(OrganizationFactory(key='course-id')) @@ -996,24 +990,6 @@ def test_list(self): self.serialize_course_run(CourseRun.objects.all().order_by(Lower('key')), many=True) ) - def test_list_edx_org_short_name_filter(self): - """ - Verify course runs filtering on edX organization. - """ - course_run_api_url_with_org_filter = '{course_run_api_url}?org={edx_org_short_name}'.format( - course_run_api_url=reverse('api:v1:course_run-list'), - edx_org_short_name=self.edx_org_short_name - ) - expected_serialized_course_runs = self.serialize_course_run( - CourseRun.objects.filter(course__authoring_organizations__key=self.edx_org_short_name).order_by(Lower('key')), - many=True - ) - - response = self.client.get(course_run_api_url_with_org_filter) - assert response.status_code == 200 - course_runs_from_response = response.data['results'] - assert course_runs_from_response == expected_serialized_course_runs - def test_list_sorted_by_course_start_date(self): """ Verify the endpoint returns a list of all course runs sorted by start date. """ url = '{root}?ordering=start'.format(root=reverse('api:v1:course_run-list')) @@ -1158,37 +1134,6 @@ def test_contains_multiple_course_runs(self): } ) - def test_contains_multiple_course_runs_edx_org_short_name_filter(self): - """ - Verify contained course runs filtering on edX organization. - """ - edx_org_course_run_key = 'course-v1:edX+DemoX+Demo_Course' - elastic_search_query_string_with_org_filter = urllib.parse.urlencode({ - 'query': 'id:course*', - 'course_run_ids': '{course_run_1_key},{course_run_2_key},{course_run_3_key}'.format( - course_run_1_key=self.course_run_2.key, - course_run_2_key=self.course_run_3.key, - course_run_3_key=edx_org_course_run_key - ), - 'org': self.edx_org_short_name - }) - course_run_api_url_with_org_filter = '{course_run_api_url}?{elastic_search_query_string_with_org_filter}'.format( - course_run_api_url=reverse('api:v1:course_run-contains'), - elastic_search_query_string_with_org_filter=elastic_search_query_string_with_org_filter - ) - expected_serialized_contained_course_runs = { - 'course_runs': { - self.course_run_2.key: False, - self.course_run_3.key: False, - edx_org_course_run_key: False - } - } - - response = self.client.get(course_run_api_url_with_org_filter) - assert response.status_code == 200 - course_runs_from_response = response.data - assert course_runs_from_response == expected_serialized_contained_course_runs - @ddt.data( {'params': {'course_run_ids': 'a/b/c'}}, {'params': {'query': 'id:course*'}}, diff --git a/course_discovery/apps/api/v1/tests/test_views/test_courses.py b/course_discovery/apps/api/v1/tests/test_views/test_courses.py index da584fe96f..9c0797b742 100644 --- a/course_discovery/apps/api/v1/tests/test_views/test_courses.py +++ b/course_discovery/apps/api/v1/tests/test_views/test_courses.py @@ -41,7 +41,6 @@ def setUp(self): self.course = CourseFactory(partner=self.partner, title='Fake Test', key='edX+Fake101', type=self.audit_type) self.org = OrganizationFactory(key='edX', partner=self.partner) self.course.authoring_organizations.add(self.org) # pylint: disable=no-member - self.edx_org_short_name = 'edx' def tearDown(self): super(CourseViewSetTests, self).tearDown() @@ -230,24 +229,6 @@ def test_list(self): self.serialize_course(Course.objects.all().order_by(Lower('key')), many=True) ) - def test_edx_org_short_name_filter(self): - """ - Verify courses filtering on edX organization. - """ - course_api_url_with_org_filter = '{courses_api_url}?org={edx_org_short_name}'.format( - courses_api_url=reverse('api:v1:course-list'), - edx_org_short_name=self.edx_org_short_name - ) - expected_serialized_courses = self.serialize_course( - Course.objects.filter(authoring_organizations__key=self.edx_org_short_name).order_by(Lower('key')), - many=True - ) - - response = self.client.get(course_api_url_with_org_filter) - assert response.status_code == 200 - courses_from_response = response.data['results'] - assert courses_from_response == expected_serialized_courses - def test_list_query(self): """ Verify the endpoint returns a filtered list of courses """ title = 'Some random title' diff --git a/course_discovery/apps/api/v1/tests/test_views/test_programs.py b/course_discovery/apps/api/v1/tests/test_views/test_programs.py index 1de1bba71f..dc8f78d574 100644 --- a/course_discovery/apps/api/v1/tests/test_views/test_programs.py +++ b/course_discovery/apps/api/v1/tests/test_views/test_programs.py @@ -214,25 +214,6 @@ def test_list(self): self.assert_list_results(self.list_path, expected, 19) - def test_edx_org_short_name_filter(self): - """ - Verify programs filtering on edX organization. - """ - edx_org_short_name = 'edx' - programs_api_url_with_org_filter = '{programs_api_url}?org={edx_org_short_name}'.format( - programs_api_url=self.list_path, - edx_org_short_name=edx_org_short_name - ) - expected_serialized_programs = self.serialize_program( - Program.objects.filter(authoring_organizations__key=edx_org_short_name), - many=True - ) - - response = self.client.get(programs_api_url_with_org_filter) - assert response.status_code == 200 - programs_from_response = response.data['results'] - assert programs_from_response == expected_serialized_programs - def test_uuids_only(self): """ Verify that the list view returns a simply list of UUIDs when the diff --git a/course_discovery/apps/api/v1/views/course_runs.py b/course_discovery/apps/api/v1/views/course_runs.py index 2be235dda2..2cfcf7c4b1 100644 --- a/course_discovery/apps/api/v1/views/course_runs.py +++ b/course_discovery/apps/api/v1/views/course_runs.py @@ -76,7 +76,6 @@ def get_queryset(self): """ q = self.request.query_params.get('q') partner = self.request.site.partner - edx_org_short_name = self.request.query_params.get('org') edit_mode = get_query_param(self.request, 'editable') or self.request.method not in SAFE_METHODS if edit_mode and q: @@ -99,7 +98,7 @@ def get_queryset(self): return qs queryset = queryset.filter(course__partner=partner) - return self.get_serializer_class().prefetch_queryset(queryset=queryset, edx_org_short_name=edx_org_short_name) + return self.get_serializer_class().prefetch_queryset(queryset=queryset) def get_serializer_context(self): context = super().get_serializer_context() @@ -172,12 +171,6 @@ def list(self, request, *args, **kwargs): type: integer paramType: query multiple: false - - name: org - description: Filter results on edx organization's short name. - required: false - type: string - paramType: query - multiple: false """ return super().list(request, *args, **kwargs) # pylint: disable=no-member @@ -393,23 +386,15 @@ def contains(self, request): type: string paramType: query multiple: false - - name: org - description: Filter results on edx organization's short name. - required: false - type: string - paramType: query - multiple: false """ query = request.GET.get('query') course_run_ids = request.GET.get('course_run_ids') partner = self.request.site.partner - edx_org_short_name = request.GET.get('org') if query and course_run_ids: course_run_ids = course_run_ids.split(',') - course_runs = CourseRun.search(query).filter(partner=partner.short_code).filter(key__in=course_run_ids) - # update "course_runs" with edx organization filter - course_runs = course_runs.filter(course__authoring_organizations__key=edx_org_short_name).values_list('key', flat=True) + course_runs = CourseRun.search(query).filter(partner=partner.short_code).filter(key__in=course_run_ids). \ + values_list('key', flat=True) contains = {course_run_id: course_run_id in course_runs for course_run_id in course_run_ids} instance = {'course_runs': contains} diff --git a/course_discovery/apps/api/v1/views/courses.py b/course_discovery/apps/api/v1/views/courses.py index 10ac4b68d6..b98152b007 100644 --- a/course_discovery/apps/api/v1/views/courses.py +++ b/course_discovery/apps/api/v1/views/courses.py @@ -98,7 +98,6 @@ def get_object(self): def get_queryset(self): partner = self.request.site.partner q = self.request.query_params.get('q') - edx_org_short_name = self.request.query_params.get('org') # We don't want to create an additional elasticsearch index right now for draft courses, so we # try to implement a basic search behavior with this pubq parameter here against key and name. pub_q = self.request.query_params.get('pubq') @@ -146,7 +145,6 @@ def get_queryset(self): queryset = self.get_serializer_class().prefetch_queryset( queryset=queryset, - edx_org_short_name=edx_org_short_name, course_runs=course_runs, partner=partner, programs=programs, @@ -447,12 +445,6 @@ def list(self, request, *args, **kwargs): type: string paramType: query multiple: false - - name: org - description: Filter results on edx organization's short name. - required: false - type: string - paramType: query - multiple: false """ return super(CourseViewSet, self).list(request, *args, **kwargs) diff --git a/course_discovery/apps/api/v1/views/programs.py b/course_discovery/apps/api/v1/views/programs.py index 93b476abe4..cc37513858 100644 --- a/course_discovery/apps/api/v1/views/programs.py +++ b/course_discovery/apps/api/v1/views/programs.py @@ -33,13 +33,12 @@ def get_queryset(self): # which happens when the queryset is stored in a class property. partner = self.request.site.partner q = self.request.query_params.get('q') - edx_org_short_name = self.request.query_params.get('org') queryset = None if q: queryset = Program.search(q) - return self.get_serializer_class().prefetch_queryset(queryset=queryset, partner=partner, edx_org_short_name=edx_org_short_name) + return self.get_serializer_class().prefetch_queryset(queryset=queryset, partner=partner) def get_serializer_context(self): context = super().get_serializer_context() @@ -156,12 +155,6 @@ def list(self, request, *args, **kwargs): type: string paramType: query multiple: false - - name: org - description: Filter results on edx organization's short name. - required: false - type: string - paramType: query - multiple: false """ if get_query_param(self.request, 'uuids_only'): # DRF serializers don't have good support for simple, flat diff --git a/course_discovery/apps/course_metadata/search_indexes.py b/course_discovery/apps/course_metadata/search_indexes.py index cbc6fd6720..2443061b6d 100644 --- a/course_discovery/apps/course_metadata/search_indexes.py +++ b/course_discovery/apps/course_metadata/search_indexes.py @@ -244,7 +244,7 @@ class CourseRunIndex(BaseCourseIndex, indexes.Indexable): license = indexes.MultiValueField(model_attr='license', faceted=True) has_enrollable_seats = indexes.BooleanField(model_attr='has_enrollable_seats', null=False) is_current_and_still_upgradeable = indexes.BooleanField(null=False) - title_override = indexes.CharField(model_attr='title_override', indexed=False, stored=True) + title_override = indexes.CharField(model_attr='title_override', indexed=False, stored=True, null=True) featured = indexes.BooleanField(model_attr='featured', null=True) is_marketing_price_set = indexes.BooleanField(model_attr='is_marketing_price_set', null=True) marketing_price_value = indexes.CharField(model_attr='marketing_price_value', null=True)