Skip to content

Commit

Permalink
feat: auto-publish children when publishing a container
Browse files Browse the repository at this point in the history
  • Loading branch information
bradenmacdonald committed Mar 5, 2025
1 parent 64bd03d commit 9a4a20e
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 10 deletions.
24 changes: 24 additions & 0 deletions openedx_learning/apps/authoring/publishing/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,30 @@ def publish_from_drafts(
published_at = datetime.now(tz=timezone.utc)

with atomic():
# If the drafts include any containers, we need to auto-publish their descendants:
# TODO: this only handles one level deep and would need to be updated to support sections > subsections > units

# Get the IDs of the ContainerVersion for any Containers whose drafts are slated to be published.
container_version_ids = (
Container.objects.filter(publishable_entity__draft__in=draft_qset)
.values_list("publishable_entity__draft__version__containerversion__pk", flat=True)
)
if container_version_ids:
# We are publishing at least one container. Check if it has any child components that aren't already slated
# to be published.
unpublished_draft_children = EntityListRow.objects.filter(
entity_list__container_versions__pk__in=container_version_ids,
entity_version=None, # Unpinned entities only
).exclude(
entity__draft__version=F("entity__published__version") # Exclude already published things
).values_list("entity__draft__pk", flat=True)
if unpublished_draft_children:
# Force these additional child components to be published at the same time by adding them to the qset:
draft_qset=Draft.objects.filter(
Q(pk__in=draft_qset.values_list("pk", flat=True)) |
Q(pk__in=unpublished_draft_children)
)

# One PublishLog for this entire publish operation.
publish_log = PublishLog(
learning_package_id=learning_package_id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class Migration(migrations.Migration):
fields=[
('publishable_entity_version', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='oel_publishing.publishableentityversion')),
('container', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='versions', to='oel_publishing.container')),
('entity_list', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='entity_list', to='oel_publishing.entitylist')),
('entity_list', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, related_name='container_versions', to='oel_publishing.entitylist')),
],
options={
'abstract': False,
Expand Down
2 changes: 1 addition & 1 deletion openedx_learning/apps/authoring/publishing/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,5 +627,5 @@ class ContainerVersion(PublishableEntityVersionMixin):
EntityList,
on_delete=models.RESTRICT,
null=False,
related_name="entity_list",
related_name="container_versions",
)
10 changes: 2 additions & 8 deletions tests/openedx_learning/apps/authoring/units/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,6 @@ def test_create_next_unit_version_with_unpinned_and_pinned_components(self):
]
assert authoring_api.get_components_in_published_unit(unit) is None

@pytest.mark.skip(reason="FIXME: auto-publishing children is not implemented yet")
def test_auto_publish_children(self):
"""
Test that publishing a unit publishes its child components automatically.
Expand Down Expand Up @@ -486,16 +485,11 @@ def test_publishing_shared_component(self):
c5_v2 = self.modify_component(c5, title="C5 version 2")

# 4️⃣ The author then publishes Unit 1, and therefore everything in it.
# FIXME: this should only require publishing the unit itself, but we don't yet do auto-publishing children
authoring_api.publish_from_drafts(
self.learning_package.pk,
draft_qset=authoring_api.get_all_drafts(self.learning_package.pk).filter(
entity_id__in=[
unit1.publishable_entity.id,
c1.publishable_entity.id,
c2.publishable_entity.id,
c3.publishable_entity.id,
],
# Note: we only publish the unit; the publishing API should auto-publish its components too.
entity_id=unit1.publishable_entity.id,
),
)

Expand Down

0 comments on commit 9a4a20e

Please sign in to comment.