Skip to content

Commit

Permalink
feat: add filter functions to publishing API [FC-0062] (#257)
Browse files Browse the repository at this point in the history
Adds filter_publishable_entities() to openedx.apps.authoring.publishing.api
(and the public openedx.api.authoring package). This also bumps the
version to 0.18.0

The motivation for this change is so that other apps can filter their
PublishableEntity querysets without having to dig into the internals of
the "publishing" app's data model relations. For instance, the
"collections" app could already answer the question, "What Publishable
Entities are in this Collection?" But to answer the question of, "What
are the Publishable Entities in this Collection that have a published
version?" requires filtering on "published__version__isnull", which is
a level of detail that we don't want to burden other apps with.

With this commit, they could call something like this instead:

    published_entities = filter_publishable_entities(
        collection.entities(),
        has_published=True,
    )

It's possible that this could be done in a more natural way with custom
Managers/QuerySets. The main concern there would be to make sure that
those come across correctly in various RelatedManagers, e.g. to make
sure that something like "Collection.entities" returns the customized
version. This is something we can follow up on in the future.
  • Loading branch information
ChrisChV authored Nov 12, 2024
1 parent 916431b commit 9d91976
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 1 deletion.
2 changes: 1 addition & 1 deletion openedx_learning/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
Open edX Learning ("Learning Core").
"""

__version__ = "0.17.0"
__version__ = "0.18.0"
20 changes: 20 additions & 0 deletions openedx_learning/apps/authoring/publishing/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"soft_delete_draft",
"reset_drafts_to_published",
"register_content_models",
"filter_publishable_entities",
]


Expand Down Expand Up @@ -493,3 +494,22 @@ def ready(self):
return PublishableContentModelRegistry.register(
content_model_cls, content_version_model_cls
)


def filter_publishable_entities(
entities: QuerySet[PublishableEntity],
has_draft=None,
has_published=None
) -> QuerySet[PublishableEntity]:
"""
Filter an entities query set.
has_draft: You can filter by entities that has a draft or not.
has_published: You can filter by entities that has a published version or not.
"""
if has_draft is not None:
entities = entities.filter(draft__version__isnull=not has_draft)
if has_published is not None:
entities = entities.filter(published__version__isnull=not has_published)

return entities
74 changes: 74 additions & 0 deletions tests/openedx_learning/apps/authoring/publishing/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,80 @@ def test_get_entities_with_unpublished_changes(self) -> None:
# should not return published soft-deleted entities.
assert len(entities) == 0

def test_filter_publishable_entities(self) -> None:
count_published = 7
count_drafts = 6
count_no_drafts = 3

for index in range(count_published):
# Create entities to publish
entity = publishing_api.create_publishable_entity(
self.learning_package.id,
f"entity_published_{index}",
created=self.now,
created_by=None,
)

publishing_api.create_publishable_entity_version(
entity.id,
version_num=1,
title=f"Entity_published_{index}",
created=self.now,
created_by=None,
)

publishing_api.publish_all_drafts(self.learning_package.id)

for index in range(count_drafts):
# Create entities with drafts
entity = publishing_api.create_publishable_entity(
self.learning_package.id,
f"entity_draft_{index}",
created=self.now,
created_by=None,
)

publishing_api.create_publishable_entity_version(
entity.id,
version_num=1,
title=f"Entity_draft_{index}",
created=self.now,
created_by=None,
)

for index in range(count_no_drafts):
# Create entities without drafts
entity = publishing_api.create_publishable_entity(
self.learning_package.id,
f"entity_no_draft_{index}",
created=self.now,
created_by=None,
)

drafts = publishing_api.filter_publishable_entities(
PublishableEntity.objects.all(),
has_draft=True,
)
assert drafts.count() == (count_published + count_drafts)

no_drafts = publishing_api.filter_publishable_entities(
PublishableEntity.objects.all(),
has_draft=False,
)
assert no_drafts.count() == count_no_drafts

published = publishing_api.filter_publishable_entities(
PublishableEntity.objects.all(),
has_published=True,
)
assert published.count() == count_published

no_published = publishing_api.filter_publishable_entities(
PublishableEntity.objects.all(),
has_published=False,
)
assert no_published.count() == (count_drafts + count_no_drafts)

def _get_published_version_num(self, entity: PublishableEntity) -> int | None:
published_version = publishing_api.get_published_version(entity.id)
if published_version is not None:
Expand Down

0 comments on commit 9d91976

Please sign in to comment.