diff --git a/course_discovery/apps/api/serializers.py b/course_discovery/apps/api/serializers.py index 92b6dd0551..ec552b57c9 100644 --- a/course_discovery/apps/api/serializers.py +++ b/course_discovery/apps/api/serializers.py @@ -2210,6 +2210,8 @@ class CourseRunSearchSerializer(HaystackSerializer): type = serializers.SerializerMethodField() is_enrollable = serializers.SerializerMethodField() seats = serializers.SerializerMethodField() + subjects = serializers.SerializerMethodField() + staff = serializers.SerializerMethodField() def get_availability(self, result): return result.object.availability @@ -2226,6 +2228,14 @@ def get_is_enrollable(self, result): def get_seats(self, result): seats = result.object.seats.all() return SeatSerializer(seats, many=True).data + + def get_subjects(self, result): + subjects = result.object.subjects.all() + return SubjectSerializer(subjects, many=True).data + + def get_staff(self, result): + staff = result.object.staff.all() + return PersonSerializer(staff, many=True).data class Meta: field_aliases = COMMON_SEARCH_FIELD_ALIASES @@ -2284,7 +2294,25 @@ class Meta: 'course_format', 'course_industry_certified_training', 'course_owner', - 'course_language' + 'course_language', + 'staff', + 'uuid', + 'status', + 'announcement', + 'external_key', + 'is_marketable', + 'invite_only', + 'outcome', + 'license', + 'hidden', + 'reporting_type', + 'eligible_for_financial_aid', + 'has_ofac_restrictions', + 'ofac_comment', + 'enrollment_count', + 'recent_enrollment_count', + 'expected_program_type', + 'expected_program_name', ) @@ -2315,9 +2343,43 @@ class Meta: class PersonSearchSerializer(HaystackSerializer): profile_image_url = serializers.SerializerMethodField() + areas_of_expertise = serializers.SerializerMethodField() + urls = serializers.SerializerMethodField() + urls_detailed = serializers.SerializerMethodField() def get_profile_image_url(self, result): return result.object.get_profile_image_url + + def get_areas_of_expertise(self, result): + areas = result.object.areas_of_expertise.all() + sorted_areas = sorted(areas, key=attrgetter('id')) + return [{ 'id': area.id, 'value': area.value} for area in sorted_areas] + + def get_social_network_url(self, url_type, obj): + # filter() isn't used to avoid discarding prefetched results. + social_networks = [network for network in obj.person_networks.all() if network.type == url_type] + + if not len(social_networks): + return None + return social_networks[0].url + + def get_urls(self, result): + return { + PersonSocialNetwork.FACEBOOK: self.get_social_network_url(PersonSocialNetwork.FACEBOOK, result.object), + PersonSocialNetwork.TWITTER: self.get_social_network_url(PersonSocialNetwork.TWITTER, result.object), + PersonSocialNetwork.BLOG: self.get_social_network_url(PersonSocialNetwork.BLOG, result.object), + } + + def get_urls_detailed(self, result): + networks = result.object.person_networks.all() + sorted_networks = sorted(networks, key=attrgetter('id')) + return [{ + 'id': network.id, + 'type': network.type, + 'title': network.title, + 'display_title': network.display_title, + 'url': network.url, + } for network in sorted_networks] @staticmethod def _get_default_field_kwargs(model, field): @@ -2339,6 +2401,14 @@ class Meta: 'marketing_id', 'marketing_url', 'designation', + 'given_name', + 'family_name', + 'slug', + 'email', + 'major_works', + 'published', + 'phone_number', + 'website', ) diff --git a/course_discovery/apps/course_metadata/search_indexes.py b/course_discovery/apps/course_metadata/search_indexes.py index fe78446917..90986de03e 100644 --- a/course_discovery/apps/course_metadata/search_indexes.py +++ b/course_discovery/apps/course_metadata/search_indexes.py @@ -261,6 +261,18 @@ class CourseRunIndex(BaseCourseIndex, indexes.Indexable): course_language = indexes.CharField(model_attr='course_language', null=True) course_owner = indexes.CharField(model_attr='course_owner', null=True) + uuid = indexes.CharField(model_attr='uuid') + external_key = indexes.CharField(model_attr='external_key', null=True) + is_marketable = indexes.BooleanField(null=True) + reporting_type = indexes.CharField(model_attr='reporting_type', null=True) + eligible_for_financial_aid = indexes.BooleanField(model_attr='eligible_for_financial_aid', null=True) + has_ofac_restrictions = indexes.BooleanField(model_attr='has_ofac_restrictions', null=True) + ofac_comment = indexes.CharField(model_attr='ofac_comment', null=True) + enrollment_count = indexes.IntegerField(model_attr='enrollment_count', null=True) + recent_enrollment_count = indexes.IntegerField(model_attr='recent_enrollment_count', null=True) + expected_program_type = indexes.CharField(model_attr='expected_program_type__name', null=True) + expected_program_name = indexes.CharField(model_attr='expected_program_name', null=True) + invite_only = indexes.BooleanField(model_attr='invite_only') def read_queryset(self, using=None): # Pre-fetch all fields required by the CourseRunSearchSerializer. Unfortunately, there's @@ -275,6 +287,9 @@ def read_queryset(self, using=None): def index_queryset(self, using=None): return super().index_queryset(using=using) + def prepare_is_marketable(self, obj): + return obj.is_marketable + def prepare_aggregation_key(self, obj): # Aggregate CourseRuns by Course key since that is how we plan to dedup CourseRuns on the marketing site. return 'courserun:{}'.format(obj.course.key) @@ -412,6 +427,14 @@ class PersonIndex(BaseIndex, indexes.Indexable): marketing_url = indexes.CharField(model_attr='marketing_url', null=True) designation = indexes.CharField(model_attr='designation', null=True) created = indexes.DateTimeField(model_attr='created') + given_name = indexes.CharField(model_attr='given_name') + family_name = indexes.CharField(model_attr='family_name', null=True) + slug = indexes.CharField(model_attr='slug') + email = indexes.CharField(model_attr='email', null=True) + major_works = indexes.CharField(model_attr='major_works', null=True) + published = indexes.BooleanField(model_attr='published') + phone_number = indexes.CharField(model_attr='phone_number', null=True) + website = indexes.CharField(model_attr='website', null=True) def prepare_aggregation_key(self, obj): return 'person:{}'.format(obj.uuid)