Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release 0.96.1 #2234

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions RELEASE.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Release Notes
=============

Version 0.96.1
--------------

- Adding topics to course and program api (#2228)

Version 0.96.0 (Released June 03, 2024)
--------------

Expand Down
1 change: 1 addition & 0 deletions courses/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ class CourseRunEnrollmentAdmin(AuditableModelAdmin):
"get_run_courseware_id",
"enrollment_mode",
"change_status",
"created_on",
)
raw_id_fields = (
"user",
Expand Down
11 changes: 11 additions & 0 deletions courses/serializers/v2/courses.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class CourseSerializer(BaseCourseSerializer):
next_run_id = serializers.SerializerMethodField()
page = BaseCoursePageSerializer(read_only=True)
programs = serializers.SerializerMethodField()
topics = serializers.SerializerMethodField()

def get_next_run_id(self, instance):
"""Get next run id"""
Expand All @@ -44,6 +45,15 @@ def get_programs(self, instance):

return None

def get_topics(self, instance):
"""List topics of a course"""
if instance.page:
return sorted(
[{"name": topic.name} for topic in instance.page.topics.all()],
key=lambda topic: topic["name"],
)
return []

class Meta:
model = models.Course
fields = [
Expand All @@ -54,6 +64,7 @@ class Meta:
"departments",
"page",
"programs",
"topics",
]


Expand Down
12 changes: 12 additions & 0 deletions courses/serializers/v2/programs.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class ProgramSerializer(serializers.ModelSerializer):
req_tree = serializers.SerializerMethodField()
page = serializers.SerializerMethodField()
departments = serializers.StringRelatedField(many=True, read_only=True)
topics = serializers.SerializerMethodField()

def get_courses(self, instance):
return [course[0].id for course in instance.courses if course[0].live]
Expand All @@ -45,6 +46,16 @@ def get_page(self, instance):
else:
return {"feature_image_src": get_thumbnail_url(None)}

def get_topics(self, instance):
"""List all topics in all courses in the program"""
topics = set( # noqa: C401
topic.name
for course in instance.courses
if course[0].page
for topic in course[0].page.topics.all()
)
return [{"name": topic} for topic in sorted(topics)]

class Meta:
model = Program
fields = [
Expand All @@ -58,6 +69,7 @@ class Meta:
"program_type",
"departments",
"live",
"topics",
]


Expand Down
12 changes: 11 additions & 1 deletion courses/serializers/v2/programs_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import pytest
from django.utils.timezone import now

from cms.factories import CoursePageFactory
from cms.serializers import ProgramPageSerializer
from courses.factories import ( # noqa: F401
CourseRunFactory,
program_with_empty_requirements,
)
from courses.models import Department
from courses.models import CoursesTopic, Department
from courses.serializers.v2.programs import (
ProgramRequirementTreeSerializer,
ProgramSerializer,
Expand All @@ -29,11 +30,13 @@ def test_serialize_program(mock_context, remove_tree, program_with_empty_require
start_date=now() + timedelta(hours=1),
)
course1 = run1.course
CoursePageFactory.create(course=run1.course)
run2 = CourseRunFactory.create(
course__page=None,
start_date=now() + timedelta(hours=2),
)
course2 = run2.course
CoursePageFactory.create(course=run2.course)
departments = [
Department.objects.create(name=f"department{num}") for num in range(3)
]
Expand All @@ -42,6 +45,7 @@ def test_serialize_program(mock_context, remove_tree, program_with_empty_require

formatted_reqs = {"required": [], "electives": []}

topics = []
if not remove_tree:
program_with_empty_requirements.add_requirement(course1)
program_with_empty_requirements.add_requirement(course2)
Expand All @@ -51,6 +55,11 @@ def test_serialize_program(mock_context, remove_tree, program_with_empty_require
formatted_reqs["electives"] = [
course.id for course in program_with_empty_requirements.elective_courses
]
topics = [CoursesTopic.objects.create(name=f"topic{num}") for num in range(3)]
course1.page.topics.set([topics[0], topics[1]])
course2.page.topics.set([topics[1], topics[2]])
course1.page.save()
course2.page.save()

data = ProgramSerializer(
instance=program_with_empty_requirements, context=mock_context
Expand All @@ -73,5 +82,6 @@ def test_serialize_program(mock_context, remove_tree, program_with_empty_require
"program_type": "Series",
"departments": [],
"live": True,
"topics": [{"name": topic.name} for topic in topics],
},
)
2 changes: 1 addition & 1 deletion courses/views/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def num_queries_from_programs(programs, version="v1"):
num_queries += num_queries_from_course(course)
num_queries += 4 + (6 * num_courses) + 1
if version == "v2":
num_queries += 6 + (12 * num_courses) + 1
num_queries += 6 + (17 * num_courses) + 1
return num_queries


Expand Down
2 changes: 1 addition & 1 deletion main/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
from main.celery_utils import OffsettingSchedule
from main.sentry import init_sentry

VERSION = "0.96.0"
VERSION = "0.96.1"

log = logging.getLogger()

Expand Down
Loading