Skip to content

Commit c643e07

Browse files
Expose readable ids on requirements objects (#3088)
1 parent f2a194b commit c643e07

File tree

5 files changed

+159
-51
lines changed

5 files changed

+159
-51
lines changed

courses/serializers/v2/programs.py

Lines changed: 67 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -231,13 +231,25 @@ def _is_requirement_elective(self, requirement):
231231
"properties": {
232232
"required": {
233233
"type": "array",
234-
"items": {"type": "integer"},
235-
"description": "List of required course IDs",
234+
"items": {
235+
"type": "object",
236+
"properties": {
237+
"id": {"type": "integer"},
238+
"readable_id": {"type": "string"},
239+
},
240+
},
241+
"description": "List of required courses with id and readable_id",
236242
},
237243
"electives": {
238244
"type": "array",
239-
"items": {"type": "integer"},
240-
"description": "List of elective course IDs",
245+
"items": {
246+
"type": "object",
247+
"properties": {
248+
"id": {"type": "integer"},
249+
"readable_id": {"type": "string"},
250+
},
251+
},
252+
"description": "List of elective courses with id and readable_id",
241253
},
242254
},
243255
},
@@ -246,13 +258,25 @@ def _is_requirement_elective(self, requirement):
246258
"properties": {
247259
"required": {
248260
"type": "array",
249-
"items": {"type": "integer"},
250-
"description": "List of required program IDs",
261+
"items": {
262+
"type": "object",
263+
"properties": {
264+
"id": {"type": "integer"},
265+
"readable_id": {"type": "string"},
266+
},
267+
},
268+
"description": "List of required programs with id and readable_id",
251269
},
252270
"electives": {
253271
"type": "array",
254-
"items": {"type": "integer"},
255-
"description": "List of elective program IDs",
272+
"items": {
273+
"type": "object",
274+
"properties": {
275+
"id": {"type": "integer"},
276+
"readable_id": {"type": "string"},
277+
},
278+
},
279+
"description": "List of elective programs with id and readable_id",
256280
},
257281
},
258282
},
@@ -273,15 +297,27 @@ def get_requirements(self, instance):
273297
)
274298
)
275299
else:
276-
# Fallback to using model properties
300+
# Fallback to using model properties
277301
return {
278302
"courses": {
279-
"required": [course.id for course in instance.required_courses],
280-
"electives": [course.id for course in instance.elective_courses],
303+
"required": [
304+
{"id": course.id, "readable_id": course.readable_id}
305+
for course in instance.required_courses
306+
],
307+
"electives": [
308+
{"id": course.id, "readable_id": course.readable_id}
309+
for course in instance.elective_courses
310+
],
281311
},
282312
"programs": {
283-
"required": [program.id for program in instance.required_programs],
284-
"electives": [program.id for program in instance.elective_programs],
313+
"required": [
314+
{"id": program.id, "readable_id": program.readable_id}
315+
for program in instance.required_programs
316+
],
317+
"electives": [
318+
{"id": program.id, "readable_id": program.readable_id}
319+
for program in instance.elective_programs
320+
],
285321
},
286322
}
287323

@@ -297,32 +333,40 @@ def get_requirements(self, instance):
297333
}
298334

299335
def _process_course_requirements_from_all(self, requirements):
300-
"""Process course requirements from all_requirements and return required/elective course IDs"""
336+
"""Process course requirements and return dicts with id and readable_id"""
301337
required_courses = []
302338
elective_courses = []
303339
for req in requirements:
304-
# Check node_type and course_id first to avoid unnecessary queries
305-
if req.node_type == ProgramRequirementNodeType.COURSE and req.course_id:
340+
# Check node_type and course first to avoid unnecessary queries
341+
if req.node_type == ProgramRequirementNodeType.COURSE and req.course:
342+
course_data = {
343+
"id": req.course.id,
344+
"readable_id": req.course.readable_id,
345+
}
306346
if self._is_requirement_elective(req):
307-
elective_courses.append(req.course_id)
347+
elective_courses.append(course_data)
308348
else:
309-
required_courses.append(req.course_id)
349+
required_courses.append(course_data)
310350
return required_courses, elective_courses
311351

312352
def _process_program_requirements_from_all(self, requirements):
313-
"""Process program requirements from all_requirements and return required/elective program IDs"""
353+
"""Process program requirements and return dicts with id and readable_id"""
314354
required_programs = []
315355
elective_programs = []
316356
for req in requirements:
317-
# Check node_type and required_program_id first to avoid unnecessary queries
357+
# Check node_type and required_program first to avoid unnecessary queries
318358
if (
319359
req.node_type == ProgramRequirementNodeType.PROGRAM
320-
and req.required_program_id
360+
and req.required_program
321361
):
362+
program_data = {
363+
"id": req.required_program.id,
364+
"readable_id": req.required_program.readable_id,
365+
}
322366
if self._is_requirement_elective(req):
323-
elective_programs.append(req.required_program_id)
367+
elective_programs.append(program_data)
324368
else:
325-
required_programs.append(req.required_program_id)
369+
required_programs.append(program_data)
326370
return required_programs, elective_programs
327371

328372
def get_required_prerequisites(self, instance) -> bool:

courses/serializers/v2/programs_test.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,20 @@ def test_serialize_program(
8383
program_with_empty_requirements.add_requirement(course2)
8484
program_with_empty_requirements.add_requirement(required_program)
8585
formatted_reqs["courses"]["required"] = [
86-
course.id for course in program_with_empty_requirements.required_courses
86+
{"id": course.id, "readable_id": course.readable_id}
87+
for course in program_with_empty_requirements.required_courses
8788
]
8889
formatted_reqs["courses"]["electives"] = [
89-
course.id for course in program_with_empty_requirements.elective_courses
90+
{"id": course.id, "readable_id": course.readable_id}
91+
for course in program_with_empty_requirements.elective_courses
9092
]
9193
formatted_reqs["programs"]["required"] = [
92-
program.id for program in program_with_empty_requirements.required_programs
94+
{"id": program.id, "readable_id": program.readable_id}
95+
for program in program_with_empty_requirements.required_programs
9396
]
9497
formatted_reqs["programs"]["electives"] = [
95-
program.id for program in program_with_empty_requirements.elective_programs
98+
{"id": program.id, "readable_id": program.readable_id}
99+
for program in program_with_empty_requirements.elective_programs
96100
]
97101
topics = [CoursesTopic.objects.create(name=f"topic{num}") for num in range(3)]
98102
course1.page.topics.set([topics[0], topics[1]])

openapi/specs/v0.yaml

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4642,26 +4642,46 @@ components:
46424642
required:
46434643
type: array
46444644
items:
4645-
type: integer
4646-
description: List of required course IDs
4645+
type: object
4646+
properties:
4647+
id:
4648+
type: integer
4649+
readable_id:
4650+
type: string
4651+
description: List of required courses with id and readable_id
46474652
electives:
46484653
type: array
46494654
items:
4650-
type: integer
4651-
description: List of elective course IDs
4655+
type: object
4656+
properties:
4657+
id:
4658+
type: integer
4659+
readable_id:
4660+
type: string
4661+
description: List of elective courses with id and readable_id
46524662
programs:
46534663
type: object
46544664
properties:
46554665
required:
46564666
type: array
46574667
items:
4658-
type: integer
4659-
description: List of required program IDs
4668+
type: object
4669+
properties:
4670+
id:
4671+
type: integer
4672+
readable_id:
4673+
type: string
4674+
description: List of required programs with id and readable_id
46604675
electives:
46614676
type: array
46624677
items:
4663-
type: integer
4664-
description: List of elective program IDs
4678+
type: object
4679+
properties:
4680+
id:
4681+
type: integer
4682+
readable_id:
4683+
type: string
4684+
description: List of elective programs with id and readable_id
46654685
readOnly: true
46664686
req_tree:
46674687
type: array

openapi/specs/v1.yaml

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4642,26 +4642,46 @@ components:
46424642
required:
46434643
type: array
46444644
items:
4645-
type: integer
4646-
description: List of required course IDs
4645+
type: object
4646+
properties:
4647+
id:
4648+
type: integer
4649+
readable_id:
4650+
type: string
4651+
description: List of required courses with id and readable_id
46474652
electives:
46484653
type: array
46494654
items:
4650-
type: integer
4651-
description: List of elective course IDs
4655+
type: object
4656+
properties:
4657+
id:
4658+
type: integer
4659+
readable_id:
4660+
type: string
4661+
description: List of elective courses with id and readable_id
46524662
programs:
46534663
type: object
46544664
properties:
46554665
required:
46564666
type: array
46574667
items:
4658-
type: integer
4659-
description: List of required program IDs
4668+
type: object
4669+
properties:
4670+
id:
4671+
type: integer
4672+
readable_id:
4673+
type: string
4674+
description: List of required programs with id and readable_id
46604675
electives:
46614676
type: array
46624677
items:
4663-
type: integer
4664-
description: List of elective program IDs
4678+
type: object
4679+
properties:
4680+
id:
4681+
type: integer
4682+
readable_id:
4683+
type: string
4684+
description: List of elective programs with id and readable_id
46654685
readOnly: true
46664686
req_tree:
46674687
type: array

openapi/specs/v2.yaml

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4642,26 +4642,46 @@ components:
46424642
required:
46434643
type: array
46444644
items:
4645-
type: integer
4646-
description: List of required course IDs
4645+
type: object
4646+
properties:
4647+
id:
4648+
type: integer
4649+
readable_id:
4650+
type: string
4651+
description: List of required courses with id and readable_id
46474652
electives:
46484653
type: array
46494654
items:
4650-
type: integer
4651-
description: List of elective course IDs
4655+
type: object
4656+
properties:
4657+
id:
4658+
type: integer
4659+
readable_id:
4660+
type: string
4661+
description: List of elective courses with id and readable_id
46524662
programs:
46534663
type: object
46544664
properties:
46554665
required:
46564666
type: array
46574667
items:
4658-
type: integer
4659-
description: List of required program IDs
4668+
type: object
4669+
properties:
4670+
id:
4671+
type: integer
4672+
readable_id:
4673+
type: string
4674+
description: List of required programs with id and readable_id
46604675
electives:
46614676
type: array
46624677
items:
4663-
type: integer
4664-
description: List of elective program IDs
4678+
type: object
4679+
properties:
4680+
id:
4681+
type: integer
4682+
readable_id:
4683+
type: string
4684+
description: List of elective programs with id and readable_id
46654685
readOnly: true
46664686
req_tree:
46674687
type: array

0 commit comments

Comments
 (0)