Fix ordering for mitxonline programs#3360
Conversation
OpenAPI ChangesNo changes detected Unexpected changes? Ensure your branch is up-to-date with |
There was a problem hiding this comment.
Pull request overview
Refactors MITx Online program child ordering so program/course relationships preserve the traversal order defined by the MITx Online req_tree, including interleaving display_mode="course" sub-programs among courses.
Changes:
- Add
get_child_positionsto derive stable(type, id) -> positionmappings fromreq_treetraversal. - Preserve requested course ID ordering in
_fetch_courses_by_ids, and stamp explicitpositionfields onto transformed courses and child programs. - Update program loaders to honor explicit
positionfor course and child-program relationships, with new/updated tests covering ordering and gap behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| learning_resources/etl/mitxonline.py | Computes child positions from req_tree, preserves course fetch order, and stamps positions onto transformed program children. |
| learning_resources/etl/mitxonline_test.py | Adds unit tests for get_child_positions and ordered _fetch_courses_by_ids; updates program transform expectations. |
| learning_resources/etl/loaders.py | Honors explicit child positions when creating relationships; adjusts pass-2 child-program relationship positioning logic. |
| learning_resources/etl/loaders_test.py | Adds loader tests ensuring explicit course positions are respected and mixed course/sub-program ordering is preserved. |
| existing_max = parent_resource.children.aggregate(Max("position")).get( | ||
| "position__max" | ||
| ) | ||
| explicit_max = max( | ||
| ( | ||
| cpd["position"] | ||
| for cpd in child_programs_data | ||
| if cpd.get("position") is not None | ||
| ), | ||
| default=-1, | ||
| ) | ||
| next_position = ( | ||
| max(existing_max if existing_max is not None else -1, explicit_max) + 1 | ||
| ) |
There was a problem hiding this comment.
I believe this comment is incorrect because of the two-pass design:
In pass 1, load_program calls learning_resource.children.all().delete(), which wipes out all prior children — both PROGRAM_COURSES and PROGRAM_PROGRAMS — and then bulk-creates fresh PROGRAM_COURSES with assigned positions.
Pass 2 only runs after pass 1 has committed. So when it computes existing_max = parent_resource.children.aggregate(Max("position")), the only children present are the freshly-created PROGRAM_COURSES from this run. Stale PROGRAM_PROGRAMS from prior runs are already gone.
40107a4 to
3a01848
Compare
03041df to
27718fd
Compare
What are the relevant tickets?
Closes https://github.com/mitodl/hq/issues/10765
Description (What does it do?)
Refactors assignment of child resource position numbers, based on the mitxonline req_tree attribute
How can this be tested?
./manage.py backpopulate_mitxonline_data