Skip to content

Commit

Permalink
Merge pull request #3839 from bjester/channel-list-query
Browse files Browse the repository at this point in the history
Optimize use of channel in unpublished_changes query
  • Loading branch information
bjester committed Nov 23, 2022
2 parents 4acc580 + 76e8ce5 commit 2b1f10b
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
[this.channelFilter]: true,
page: this.$route.query.page || 1,
exclude: this.currentChannelId,
ordering: this.channelFilter === 'public' ? 'name' : '-modified',
}).then(page => {
this.pageCount = page.total_pages;
this.channels = page.results;
Expand Down
30 changes: 22 additions & 8 deletions contentcuration/contentcuration/viewsets/channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,9 +382,18 @@ def format_demo_server_url(item):


def _unpublished_changes_query(channel):
"""
:param channel: Either an `OuterRef` or `Channel` object
:type channel: Channel|OuterRef
:return: QuerySet for unpublished changes
"""
# double wrap the channel if it's an outer ref so that we can match the outermost channel
# to optimize query performance
channel_ref = OuterRef(channel) if isinstance(channel, OuterRef) else channel

return Change.objects.filter(
server_rev__gt=Coalesce(Change.objects.filter(
channel=OuterRef("channel"),
channel=channel_ref,
change_type=PUBLISHED,
errored=False
).values("server_rev").order_by("-server_rev")[:1], Value(0)),
Expand All @@ -400,6 +409,8 @@ class ChannelViewSet(ValuesViewset):
serializer_class = ChannelSerializer
pagination_class = ChannelListPagination
filterset_class = ChannelFilter
ordering_fields = ["modified", "name"]
ordering = "-modified"

field_map = channel_field_map
values = base_channel_values + ("edit", "view", "unpublished_changes")
Expand All @@ -412,6 +423,15 @@ def get_queryset(self):
queryset = super(ChannelViewSet, self).get_queryset()
user_id = not self.request.user.is_anonymous and self.request.user.id
user_queryset = User.objects.filter(id=user_id)
# Add the last modified node modified value as the channel last modified
channel_main_tree_nodes = ContentNode.objects.filter(
tree_id=OuterRef("main_tree__tree_id")
)
queryset = queryset.annotate(
modified=Subquery(
channel_main_tree_nodes.values("modified").order_by("-modified")[:1]
)
)

return queryset.annotate(
edit=Exists(user_queryset.filter(editable_channels=OuterRef("id"))),
Expand All @@ -434,12 +454,6 @@ def annotate_queryset(self, queryset):
queryset = queryset.annotate(
count=SQCount(non_topic_content_ids, field="content_id"),
)
# Add the last modified node modified value as the channel last modified
queryset = queryset.annotate(
modified=Subquery(
channel_main_tree_nodes.values("modified").order_by("-modified")[:1]
)
)

queryset = queryset.annotate(unpublished_changes=Exists(_unpublished_changes_query(OuterRef("id"))))

Expand Down Expand Up @@ -488,7 +502,7 @@ def publish(self, pk, version_notes="", language=None):
"publishing": False,
"primary_token": channel.get_human_token().token,
"last_published": channel.last_published,
"unpublished_changes": _unpublished_changes_query(channel.id).exists()
"unpublished_changes": _unpublished_changes_query(channel).exists()
}, channel_id=channel.id
),
], applied=True)
Expand Down

0 comments on commit 2b1f10b

Please sign in to comment.