diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 521019aec3..64671a724c 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -9,6 +9,7 @@ Changelog * Add `PageQuerySet.private` method as an alias of `not_public` (Mehrdad Moradizadeh) * Most images in the admin will now only load once they are visible on screen (Jake Howard) * Allow setting default attributes on image tags (Jake Howard) + * Optimise the performance of the Wagtail userbar to remove duplicated queries, improving page loads when viewing live pages while signed in (Jake Howard) * Fix: Prevent `PageQuerySet.not_public` from returning all pages when no page restrictions exist (Mehrdad Moradizadeh) diff --git a/docs/releases/4.1.md b/docs/releases/4.1.md index 343540a3d0..6e3bb5445d 100644 --- a/docs/releases/4.1.md +++ b/docs/releases/4.1.md @@ -17,6 +17,7 @@ Wagtail 4.1 is designated a Long Term Support (LTS) release. Long Term Support r * Add `PageQuerySet.private` method as an alias of `not_public` (Mehrdad Moradizadeh) * Most images in the admin will now only load once they are visible on screen (Jake Howard) * Allow setting default attributes on image tags [](adding_default_attributes_to_images) (Jake Howard) + * Optimise the performance of the Wagtail userbar to remove duplicated queries, improving page loads when viewing live pages while signed in (Jake Howard) ### Bug fixes diff --git a/wagtail/admin/templatetags/wagtailuserbar.py b/wagtail/admin/templatetags/wagtailuserbar.py index 6e50d51af8..92db2ae5ef 100644 --- a/wagtail/admin/templatetags/wagtailuserbar.py +++ b/wagtail/admin/templatetags/wagtailuserbar.py @@ -64,28 +64,21 @@ def wagtailuserbar(context, position="bottom-right"): if page and page.id: if revision_id: + revision = Revision.page_revisions.get(id=revision_id) items = [ AdminItem(), - ExplorePageItem( - Revision.page_revisions.get(id=revision_id).content_object - ), - EditPageItem( - Revision.page_revisions.get(id=revision_id).content_object - ), - ApproveModerationEditPageItem( - Revision.page_revisions.get(id=revision_id) - ), - RejectModerationEditPageItem( - Revision.page_revisions.get(id=revision_id) - ), + ExplorePageItem(revision.content_object), + EditPageItem(revision.content_object), + ApproveModerationEditPageItem(revision), + RejectModerationEditPageItem(revision), ] else: # Not a revision items = [ AdminItem(), - ExplorePageItem(Page.objects.get(id=page.id)), - EditPageItem(Page.objects.get(id=page.id)), - AddPageItem(Page.objects.get(id=page.id)), + ExplorePageItem(page), + EditPageItem(page), + AddPageItem(page), ] else: # Not a page. diff --git a/wagtail/admin/tests/test_userbar.py b/wagtail/admin/tests/test_userbar.py index 895545caf0..5ffcaf00e6 100644 --- a/wagtail/admin/tests/test_userbar.py +++ b/wagtail/admin/tests/test_userbar.py @@ -16,26 +16,46 @@ class TestUserbarTag(TestCase, WagtailTestUtils): ) self.homepage = Page.objects.get(id=2) - def dummy_request(self, user=None, is_preview=False, in_preview_panel=False): + def dummy_request( + self, user=None, *, is_preview=False, in_preview_panel=False, revision_id=None + ): request = RequestFactory().get("/") request.user = user or AnonymousUser() request.is_preview = is_preview request.in_preview_panel = in_preview_panel + if revision_id: + request.revision_id = revision_id return request def test_userbar_tag(self): template = Template("{% load wagtailuserbar %}{% wagtailuserbar %}") - content = template.render( - Context( - { - PAGE_TEMPLATE_VAR: self.homepage, - "request": self.dummy_request(self.user), - } - ) + context = Context( + { + PAGE_TEMPLATE_VAR: self.homepage, + "request": self.dummy_request(self.user), + } ) + with self.assertNumQueries(5): + content = template.render(context) self.assertIn("<!-- Wagtail user bar embed code -->", content) + def test_userbar_tag_revision(self): + self.homepage.save_revision(user=self.user, submitted_for_moderation=True) + revision = self.homepage.get_latest_revision() + template = Template("{% load wagtailuserbar %}{% wagtailuserbar %}") + context = Context( + { + PAGE_TEMPLATE_VAR: self.homepage, + "request": self.dummy_request(self.user, revision_id=revision.id), + } + ) + with self.assertNumQueries(7): + content = template.render(context) + + self.assertIn("<!-- Wagtail user bar embed code -->", content) + self.assertIn("Approve", content) + def test_userbar_does_not_break_without_request(self): template = Template("{% load wagtailuserbar %}{% wagtailuserbar %}boom") content = template.render(Context({}))