diff --git a/wagtail/admin/templates/wagtailadmin/shared/workflow_status.html b/wagtail/admin/templates/wagtailadmin/shared/workflow_status.html
index 3ba72f78bc..cf8283c4e5 100644
--- a/wagtail/admin/templates/wagtailadmin/shared/workflow_status.html
+++ b/wagtail/admin/templates/wagtailadmin/shared/workflow_status.html
@@ -7,7 +7,7 @@
{{ workflow.name }}
{% if current_task_number %}
- {% blocktrans %} Task {{ current_task_number }} of {{ workflow_tasks.count }}{% endblocktrans %}: {{ task.name }}
+ {% blocktrans with workflow_tasks|length as total_tasks %} Task {{ current_task_number }} of {{ total_tasks }}{% endblocktrans %}: {{ task.name }}
{% else %}
{% trans 'Task' %}: {{ task.name }}
{% endif %}
diff --git a/wagtail/admin/views/pages.py b/wagtail/admin/views/pages.py
index 13bd74a1d6..67e72bd93e 100644
--- a/wagtail/admin/views/pages.py
+++ b/wagtail/admin/views/pages.py
@@ -426,7 +426,7 @@ def edit(request, page_id):
workflow_tasks = workflow_state.all_tasks_with_status()
# add a warning message if tasks have been approved and may need to be re-approved
- task_has_been_approved = workflow_tasks.filter(status='approved').exists()
+ task_has_been_approved = any(filter(lambda task: task.status == 'approved', workflow_tasks))
# TODO: add icon to message when we have added a workflows icon
if request.method == 'GET':
@@ -439,13 +439,13 @@ def edit(request, page_id):
))
# Check for revisions still undergoing moderation and warn
- if workflow_tasks.count() == 1:
+ if len(workflow_tasks) == 1:
# If only one task in workflow, show simple message
workflow_info = _("This page is currently awaiting moderation")
elif current_task_number:
- workflow_info = format_html(_("Page '{}' is on Task {} of {}: '{}' in Workflow '{}'. "), page.get_admin_display_title(), current_task_number, workflow_tasks.count(), task.name, workflow.name)
+ workflow_info = format_html(_("Page '{}' is on Task {} of {}: '{}' in Workflow '{}'. "), page.get_admin_display_title(), current_task_number, len(workflow_tasks), task.name, workflow.name)
else:
- workflow_info = format_html(_("Page '{}' is on Task '{}' in Workflow '{}'. "), page.get_admin_display_title(), current_task_number, workflow_tasks.count(), task.name, workflow.name)
+ workflow_info = format_html(_("Page '{}' is on Task '{}' in Workflow '{}'. "), page.get_admin_display_title(), current_task_number, len(workflow_tasks), task.name, workflow.name)
if task_has_been_approved and getattr(settings, 'WAGTAIL_WORKFLOW_REQUIRE_REAPPROVAL_ON_EDIT', True):
messages.warning(request, mark_safe(workflow_info + _("Editing this Page will cause completed Tasks to need re-approval.")), buttons=buttons, extra_tags="workflow")
diff --git a/wagtail/core/models.py b/wagtail/core/models.py
index db73043dfa..937420f47a 100644
--- a/wagtail/core/models.py
+++ b/wagtail/core/models.py
@@ -2846,22 +2846,33 @@ class WorkflowState(models.Model):
def all_tasks_with_status(self):
"""
- Returns a queryset of Task objects that are linked with this workflow state's
+ Returns a list of Task objects that are linked with this workflow state's
workflow. The status of that task in this workflow state is annotated in the
- `.status` field.
+ `.status` field. And a displayable version of that status is annotated in the
+ `.status_display` field.
This is different to querying TaskState as it also returns tasks that haven't
been started yet (so won't have a TaskState).
"""
- return self.workflow.tasks.annotate(
- status=Subquery(
- TaskState.objects.filter(
- task_id=OuterRef('id'),
- workflow_state_id=self.id,
- ).values('status')
+ tasks = list(
+ self.workflow.tasks.annotate(
+ status=Subquery(
+ TaskState.objects.filter(
+ task_id=OuterRef('id'),
+ workflow_state_id=self.id,
+ page_revision_id=self.page.revisions.order_by('-created_at', '-id').values_list('id', flat=True).first()
+ ).values('status')
+ ),
)
)
+ # Manually annotate status_display
+ status_choices = dict(self.STATUS_CHOICES)
+ for task in tasks:
+ task.status_display = status_choices.get(task.status, _("Not started"))
+
+ return tasks
+
class Meta:
verbose_name = _('Workflow state')
verbose_name_plural = _('Workflow states')