prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Stray checkbox on locked pages report
  ### Issue Summary
  
  The Locked Pages report (and possibly others inheriting from PageReportView) has a stray additional column with a checkbox, presumably from the bulk actions feature, which causes the column headings to get out of step:
  
  ![Screenshot 2021-11-04 at 14 38 33](https://user-images.githubusercontent.com/85097/140334621-38a41691-f20d-48b5-b38c-3d2d7ed69519.png)
  
  Thanks to @Tijani-Dia for reporting.
  
  ### Steps to Reproduce
  
  1. Start a new project with `wagtail start myproject` / `./manage.py migrate` / `./manage.py createsuperuser`
  2. Log in, edit the homepage, select 'Lock' from the action menu
  3. Go to Reports -> Locked pages
  
  * I have confirmed that this issue can be reproduced as described on a fresh Wagtail project: yes
  
  
  ### Technical details
  
  * Python version: 3.8.0
  * Django version: 3.2.8
  * Wagtail version: 2.15
  * Browser version: Chrome 95.0.4638.54
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `wagtail/admin/views/pages/listing.py`
  Content:
  ```
  1 from django.conf import settings
  2 from django.core.paginator import Paginator
  3 from django.db.models import Count
  4 from django.shortcuts import get_object_or_404, redirect
  5 from django.template.response import TemplateResponse
  6 from django.urls import reverse
  7 
  8 from wagtail.admin.auth import user_has_any_page_permission, user_passes_test
  9 from wagtail.admin.navigation import get_explorable_root_page
  10 from wagtail.core import hooks
  11 from wagtail.core.models import Page, UserPagePermissionsProxy
  12 
  13 
  14 @user_passes_test(user_has_any_page_permission)
  15 def index(request, parent_page_id=None):
  16     if parent_page_id:
  17         parent_page = get_object_or_404(Page, id=parent_page_id)
  18     else:
  19         parent_page = Page.get_first_root_node()
  20 
  21     # This will always succeed because of the @user_passes_test above.
  22     root_page = get_explorable_root_page(request.user)
  23 
  24     # If this page isn't a descendant of the user's explorable root page,
  25     # then redirect to that explorable root page instead.
  26     if not (
  27         parent_page.pk == root_page.pk
  28         or parent_page.is_descendant_of(root_page)
  29     ):
  30         return redirect('wagtailadmin_explore', root_page.pk)
  31 
  32     parent_page = parent_page.specific
  33 
  34     user_perms = UserPagePermissionsProxy(request.user)
  35     pages = (
  36         parent_page.get_children().prefetch_related(
  37             "content_type", "sites_rooted_here"
  38         )
  39         & user_perms.explorable_pages()
  40     )
  41 
  42     # Get page ordering
  43     ordering = request.GET.get('ordering', '-latest_revision_created_at')
  44     if ordering not in [
  45         'title',
  46         '-title',
  47         'content_type',
  48         '-content_type',
  49         'live', '-live',
  50         'latest_revision_created_at',
  51         '-latest_revision_created_at',
  52         'ord'
  53     ]:
  54         ordering = '-latest_revision_created_at'
  55 
  56     if ordering == 'ord':
  57         # preserve the native ordering from get_children()
  58         pass
  59     elif ordering == 'latest_revision_created_at':
  60         # order by oldest revision first.
  61         # Special case NULL entries - these should go at the top of the list.
  62         # Do this by annotating with Count('latest_revision_created_at'),
  63         # which returns 0 for these
  64         pages = pages.annotate(
  65             null_position=Count('latest_revision_created_at')
  66         ).order_by('null_position', 'latest_revision_created_at')
  67     elif ordering == '-latest_revision_created_at':
  68         # order by oldest revision first.
  69         # Special case NULL entries - these should go at the end of the list.
  70         pages = pages.annotate(
  71             null_position=Count('latest_revision_created_at')
  72         ).order_by('-null_position', '-latest_revision_created_at')
  73     else:
  74         pages = pages.order_by(ordering)
  75 
  76     # Don't paginate if sorting by page order - all pages must be shown to
  77     # allow drag-and-drop reordering
  78     do_paginate = ordering != 'ord'
  79 
  80     # We want specific page instances, but do not need streamfield values here
  81     pages = pages.defer_streamfields().specific()
  82 
  83     # allow hooks defer_streamfieldsyset
  84     for hook in hooks.get_hooks('construct_explorer_page_queryset'):
  85         pages = hook(parent_page, pages, request)
  86 
  87     # Annotate queryset with various states to be used later for performance optimisations
  88     if getattr(settings, 'WAGTAIL_WORKFLOW_ENABLED', True):
  89         pages = pages.prefetch_workflow_states()
  90 
  91     pages = pages.annotate_site_root_state().annotate_approved_schedule()
  92 
  93     # Pagination
  94     if do_paginate:
  95         paginator = Paginator(pages, per_page=50)
  96         pages = paginator.get_page(request.GET.get('p'))
  97 
  98     context = {
  99         'parent_page': parent_page.specific,
  100         'ordering': ordering,
  101         'pagination_query_params': "ordering=%s" % ordering,
  102         'pages': pages,
  103         'do_paginate': do_paginate,
  104         'locale': None,
  105         'translations': [],
  106         'show_ordering_column': request.GET.get('ordering') == 'ord'
  107     }
  108 
  109     if getattr(settings, 'WAGTAIL_I18N_ENABLED', False) and not parent_page.is_root():
  110         context.update({
  111             'locale': parent_page.locale,
  112             'translations': [
  113                 {
  114                     'locale': translation.locale,
  115                     'url': reverse('wagtailadmin_explore', args=[translation.id]),
  116                 }
  117                 for translation in parent_page.get_translations().only('id', 'locale').select_related('locale')
  118             ],
  119         })
  120 
  121     return TemplateResponse(request, 'wagtailadmin/pages/index.html', context)
  122
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/wagtail/admin/views/pages/listing.py b/wagtail/admin/views/pages/listing.py
  --- a/wagtail/admin/views/pages/listing.py
  +++ b/wagtail/admin/views/pages/listing.py
  @@ -95,6 +95,8 @@
           paginator = Paginator(pages, per_page=50)
           pages = paginator.get_page(request.GET.get('p'))
   
  +    show_ordering_column = request.GET.get('ordering') == 'ord'
  +
       context = {
           'parent_page': parent_page.specific,
           'ordering': ordering,
  @@ -103,7 +105,8 @@
           'do_paginate': do_paginate,
           'locale': None,
           'translations': [],
  -        'show_ordering_column': request.GET.get('ordering') == 'ord'
  +        'show_ordering_column': show_ordering_column,
  +        'show_bulk_actions': not show_ordering_column,
       }
   
       if getattr(settings, 'WAGTAIL_I18N_ENABLED', False) and not parent_page.is_root():
  
verification_info: {"golden_diff": "diff --git a/wagtail/admin/views/pages/listing.py b/wagtail/admin/views/pages/listing.py\n--- a/wagtail/admin/views/pages/listing.py\n+++ b/wagtail/admin/views/pages/listing.py\n@@ -95,6 +95,8 @@\n         paginator = Paginator(pages, per_page=50)\n         pages = paginator.get_page(request.GET.get('p'))\n \n+    show_ordering_column = request.GET.get('ordering') == 'ord'\n+\n     context = {\n         'parent_page': parent_page.specific,\n         'ordering': ordering,\n@@ -103,7 +105,8 @@\n         'do_paginate': do_paginate,\n         'locale': None,\n         'translations': [],\n-        'show_ordering_column': request.GET.get('ordering') == 'ord'\n+        'show_ordering_column': show_ordering_column,\n+        'show_bulk_actions': not show_ordering_column,\n     }\n \n     if getattr(settings, 'WAGTAIL_I18N_ENABLED', False) and not parent_page.is_root():\n", "issue": "Stray checkbox on locked pages report\n### Issue Summary\r\n\r\nThe Locked Pages report (and possibly others inheriting from PageReportView) has a stray additional column with a checkbox, presumably from the bulk actions feature, which causes the column headings to get out of step:\r\n\r\n![Screenshot 2021-11-04 at 14 38 33](https://user-images.githubusercontent.com/85097/140334621-38a41691-f20d-48b5-b38c-3d2d7ed69519.png)\r\n\r\nThanks to @Tijani-Dia for reporting.\r\n\r\n### Steps to Reproduce\r\n\r\n1. Start a new project with `wagtail start myproject` / `./manage.py migrate` / `./manage.py createsuperuser`\r\n2. Log in, edit the homepage, select 'Lock' from the action menu\r\n3. Go to Reports -> Locked pages\r\n\r\n* I have confirmed that this issue can be reproduced as described on a fresh Wagtail project: yes\r\n\r\n\r\n### Technical details\r\n\r\n* Python version: 3.8.0\r\n* Django version: 3.2.8\r\n* Wagtail version: 2.15\r\n* Browser version: Chrome 95.0.4638.54\r\n\n", "before_files": [{"content": "from django.conf import settings\nfrom django.core.paginator import Paginator\nfrom django.db.models import Count\nfrom django.shortcuts import get_object_or_404, redirect\nfrom django.template.response import TemplateResponse\nfrom django.urls import reverse\n\nfrom wagtail.admin.auth import user_has_any_page_permission, user_passes_test\nfrom wagtail.admin.navigation import get_explorable_root_page\nfrom wagtail.core import hooks\nfrom wagtail.core.models import Page, UserPagePermissionsProxy\n\n\n@user_passes_test(user_has_any_page_permission)\ndef index(request, parent_page_id=None):\n    if parent_page_id:\n        parent_page = get_object_or_404(Page, id=parent_page_id)\n    else:\n        parent_page = Page.get_first_root_node()\n\n    # This will always succeed because of the @user_passes_test above.\n    root_page = get_explorable_root_page(request.user)\n\n    # If this page isn't a descendant of the user's explorable root page,\n    # then redirect to that explorable root page instead.\n    if not (\n        parent_page.pk == root_page.pk\n        or parent_page.is_descendant_of(root_page)\n    ):\n        return redirect('wagtailadmin_explore', root_page.pk)\n\n    parent_page = parent_page.specific\n\n    user_perms = UserPagePermissionsProxy(request.user)\n    pages = (\n        parent_page.get_children().prefetch_related(\n            \"content_type\", \"sites_rooted_here\"\n        )\n        & user_perms.explorable_pages()\n    )\n\n    # Get page ordering\n    ordering = request.GET.get('ordering', '-latest_revision_created_at')\n    if ordering not in [\n        'title',\n        '-title',\n        'content_type',\n        '-content_type',\n        'live', '-live',\n        'latest_revision_created_at',\n        '-latest_revision_created_at',\n        'ord'\n    ]:\n        ordering = '-latest_revision_created_at'\n\n    if ordering == 'ord':\n        # preserve the native ordering from get_children()\n        pass\n    elif ordering == 'latest_revision_created_at':\n        # order by oldest revision first.\n        # Special case NULL entries - these should go at the top of the list.\n        # Do this by annotating with Count('latest_revision_created_at'),\n        # which returns 0 for these\n        pages = pages.annotate(\n            null_position=Count('latest_revision_created_at')\n        ).order_by('null_position', 'latest_revision_created_at')\n    elif ordering == '-latest_revision_created_at':\n        # order by oldest revision first.\n        # Special case NULL entries - these should go at the end of the list.\n        pages = pages.annotate(\n            null_position=Count('latest_revision_created_at')\n        ).order_by('-null_position', '-latest_revision_created_at')\n    else:\n        pages = pages.order_by(ordering)\n\n    # Don't paginate if sorting by page order - all pages must be shown to\n    # allow drag-and-drop reordering\n    do_paginate = ordering != 'ord'\n\n    # We want specific page instances, but do not need streamfield values here\n    pages = pages.defer_streamfields().specific()\n\n    # allow hooks defer_streamfieldsyset\n    for hook in hooks.get_hooks('construct_explorer_page_queryset'):\n        pages = hook(parent_page, pages, request)\n\n    # Annotate queryset with various states to be used later for performance optimisations\n    if getattr(settings, 'WAGTAIL_WORKFLOW_ENABLED', True):\n        pages = pages.prefetch_workflow_states()\n\n    pages = pages.annotate_site_root_state().annotate_approved_schedule()\n\n    # Pagination\n    if do_paginate:\n        paginator = Paginator(pages, per_page=50)\n        pages = paginator.get_page(request.GET.get('p'))\n\n    context = {\n        'parent_page': parent_page.specific,\n        'ordering': ordering,\n        'pagination_query_params': \"ordering=%s\" % ordering,\n        'pages': pages,\n        'do_paginate': do_paginate,\n        'locale': None,\n        'translations': [],\n        'show_ordering_column': request.GET.get('ordering') == 'ord'\n    }\n\n    if getattr(settings, 'WAGTAIL_I18N_ENABLED', False) and not parent_page.is_root():\n        context.update({\n            'locale': parent_page.locale,\n            'translations': [\n                {\n                    'locale': translation.locale,\n                    'url': reverse('wagtailadmin_explore', args=[translation.id]),\n                }\n                for translation in parent_page.get_translations().only('id', 'locale').select_related('locale')\n            ],\n        })\n\n    return TemplateResponse(request, 'wagtailadmin/pages/index.html', context)\n", "path": "wagtail/admin/views/pages/listing.py"}], "after_files": [{"content": "from django.conf import settings\nfrom django.core.paginator import Paginator\nfrom django.db.models import Count\nfrom django.shortcuts import get_object_or_404, redirect\nfrom django.template.response import TemplateResponse\nfrom django.urls import reverse\n\nfrom wagtail.admin.auth import user_has_any_page_permission, user_passes_test\nfrom wagtail.admin.navigation import get_explorable_root_page\nfrom wagtail.core import hooks\nfrom wagtail.core.models import Page, UserPagePermissionsProxy\n\n\n@user_passes_test(user_has_any_page_permission)\ndef index(request, parent_page_id=None):\n    if parent_page_id:\n        parent_page = get_object_or_404(Page, id=parent_page_id)\n    else:\n        parent_page = Page.get_first_root_node()\n\n    # This will always succeed because of the @user_passes_test above.\n    root_page = get_explorable_root_page(request.user)\n\n    # If this page isn't a descendant of the user's explorable root page,\n    # then redirect to that explorable root page instead.\n    if not (\n        parent_page.pk == root_page.pk\n        or parent_page.is_descendant_of(root_page)\n    ):\n        return redirect('wagtailadmin_explore', root_page.pk)\n\n    parent_page = parent_page.specific\n\n    user_perms = UserPagePermissionsProxy(request.user)\n    pages = (\n        parent_page.get_children().prefetch_related(\n            \"content_type\", \"sites_rooted_here\"\n        )\n        & user_perms.explorable_pages()\n    )\n\n    # Get page ordering\n    ordering = request.GET.get('ordering', '-latest_revision_created_at')\n    if ordering not in [\n        'title',\n        '-title',\n        'content_type',\n        '-content_type',\n        'live', '-live',\n        'latest_revision_created_at',\n        '-latest_revision_created_at',\n        'ord'\n    ]:\n        ordering = '-latest_revision_created_at'\n\n    if ordering == 'ord':\n        # preserve the native ordering from get_children()\n        pass\n    elif ordering == 'latest_revision_created_at':\n        # order by oldest revision first.\n        # Special case NULL entries - these should go at the top of the list.\n        # Do this by annotating with Count('latest_revision_created_at'),\n        # which returns 0 for these\n        pages = pages.annotate(\n            null_position=Count('latest_revision_created_at')\n        ).order_by('null_position', 'latest_revision_created_at')\n    elif ordering == '-latest_revision_created_at':\n        # order by oldest revision first.\n        # Special case NULL entries - these should go at the end of the list.\n        pages = pages.annotate(\n            null_position=Count('latest_revision_created_at')\n        ).order_by('-null_position', '-latest_revision_created_at')\n    else:\n        pages = pages.order_by(ordering)\n\n    # Don't paginate if sorting by page order - all pages must be shown to\n    # allow drag-and-drop reordering\n    do_paginate = ordering != 'ord'\n\n    # We want specific page instances, but do not need streamfield values here\n    pages = pages.defer_streamfields().specific()\n\n    # allow hooks defer_streamfieldsyset\n    for hook in hooks.get_hooks('construct_explorer_page_queryset'):\n        pages = hook(parent_page, pages, request)\n\n    # Annotate queryset with various states to be used later for performance optimisations\n    if getattr(settings, 'WAGTAIL_WORKFLOW_ENABLED', True):\n        pages = pages.prefetch_workflow_states()\n\n    pages = pages.annotate_site_root_state().annotate_approved_schedule()\n\n    # Pagination\n    if do_paginate:\n        paginator = Paginator(pages, per_page=50)\n        pages = paginator.get_page(request.GET.get('p'))\n\n    show_ordering_column = request.GET.get('ordering') == 'ord'\n\n    context = {\n        'parent_page': parent_page.specific,\n        'ordering': ordering,\n        'pagination_query_params': \"ordering=%s\" % ordering,\n        'pages': pages,\n        'do_paginate': do_paginate,\n        'locale': None,\n        'translations': [],\n        'show_ordering_column': show_ordering_column,\n        'show_bulk_actions': not show_ordering_column,\n    }\n\n    if getattr(settings, 'WAGTAIL_I18N_ENABLED', False) and not parent_page.is_root():\n        context.update({\n            'locale': parent_page.locale,\n            'translations': [\n                {\n                    'locale': translation.locale,\n                    'url': reverse('wagtailadmin_explore', args=[translation.id]),\n                }\n                for translation in parent_page.get_translations().only('id', 'locale').select_related('locale')\n            ],\n        })\n\n    return TemplateResponse(request, 'wagtailadmin/pages/index.html', context)\n", "path": "wagtail/admin/views/pages/listing.py"}]}