diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 61c9c9fc12..04cdea205b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -26,6 +26,7 @@ Changelog * Render the Wagtail User Bar on non `Page` views (Caitlin White, Coen van der Kamp) * Add ability to define `form_classname` on `ListBlock` & `StreamBlock` (LB (Ben Johnston)) * Add documentation about how to use `Rustface` for image feature detection (Neal Todd) + * Improve performance of public/not_public queries in `PageQuerySet` (Timothy Bautista) * Fix: Support IPv6 domain (Alex Gleason, Coen van der Kamp) * Fix: Ensure link to add a new user works when no users are visible in the users list (LB (Ben Johnston)) * Fix: `AbstractEmailForm` saved submission fields are now aligned with the email content fields, `form.cleaned_data` will be used instead of `form.fields` (Haydn Greatnews) diff --git a/docs/releases/2.10.rst b/docs/releases/2.10.rst index b89ca822c2..8c33603ea5 100644 --- a/docs/releases/2.10.rst +++ b/docs/releases/2.10.rst @@ -35,6 +35,7 @@ Other features * Render the Wagtail User Bar on non ``Page`` views (Caitlin White, Coen van der Kamp) * Add ability to define ``form_classname`` on ``ListBlock`` & ``StreamBlock`` (LB (Ben Johnston)) * Add documentation about how to use ``Rustface`` for image feature detection (Neal Todd) + * Improve performance of public/not_public queries in ``PageQuerySet`` (Timothy Bautista) Bug fixes diff --git a/wagtail/contrib/sitemaps/tests.py b/wagtail/contrib/sitemaps/tests.py index eb35daa871..28e2c994e6 100644 --- a/wagtail/contrib/sitemaps/tests.py +++ b/wagtail/contrib/sitemaps/tests.py @@ -73,7 +73,7 @@ class TestSitemapGenerator(TestCase): req_protocol = request.scheme sitemap = Sitemap() - with self.assertNumQueries(18): + with self.assertNumQueries(17): urls = [url['location'] for url in sitemap.get_urls(1, django_site, req_protocol)] self.assertIn('http://localhost/', urls) # Homepage @@ -88,7 +88,7 @@ class TestSitemapGenerator(TestCase): # pre-seed find_for_request cache, so that it's not counted towards the query count Site.find_for_request(request) - with self.assertNumQueries(16): + with self.assertNumQueries(15): urls = [url['location'] for url in sitemap.get_urls(1, django_site, req_protocol)] self.assertIn('http://localhost/', urls) # Homepage diff --git a/wagtail/core/query.py b/wagtail/core/query.py index fa38cba009..6d130a15f3 100644 --- a/wagtail/core/query.py +++ b/wagtail/core/query.py @@ -220,7 +220,7 @@ class PageQuerySet(SearchableQuerySetMixin, TreeQuerySet): from wagtail.core.models import PageViewRestriction q = Q() - for restriction in PageViewRestriction.objects.all(): + for restriction in PageViewRestriction.objects.select_related('page').all(): q &= ~self.descendant_of_q(restriction.page, inclusive=True) return q diff --git a/wagtail/core/tests/test_page_queryset.py b/wagtail/core/tests/test_page_queryset.py index 820170a970..f3f4fdcd5e 100644 --- a/wagtail/core/tests/test_page_queryset.py +++ b/wagtail/core/tests/test_page_queryset.py @@ -366,17 +366,18 @@ class TestPageQuerySet(TestCase): # Add PageViewRestriction to events_index PageViewRestriction.objects.create(page=events_index, password='hello') - # Get public pages - pages = Page.objects.public() + with self.assertNumQueries(4): + # Get public pages + pages = Page.objects.public() - # Check that the homepage is in the results - self.assertTrue(pages.filter(id=homepage.id).exists()) + # Check that the homepage is in the results + self.assertTrue(pages.filter(id=homepage.id).exists()) - # Check that the events index is not in the results - self.assertFalse(pages.filter(id=events_index.id).exists()) + # Check that the events index is not in the results + self.assertFalse(pages.filter(id=events_index.id).exists()) - # Check that the event is not in the results - self.assertFalse(pages.filter(id=event.id).exists()) + # Check that the event is not in the results + self.assertFalse(pages.filter(id=event.id).exists()) def test_not_public(self): events_index = Page.objects.get(url_path='/home/events/') @@ -386,17 +387,18 @@ class TestPageQuerySet(TestCase): # Add PageViewRestriction to events_index PageViewRestriction.objects.create(page=events_index, password='hello') - # Get public pages - pages = Page.objects.not_public() + with self.assertNumQueries(4): + # Get public pages + pages = Page.objects.not_public() - # Check that the homepage is not in the results - self.assertFalse(pages.filter(id=homepage.id).exists()) + # Check that the homepage is not in the results + self.assertFalse(pages.filter(id=homepage.id).exists()) - # Check that the events index is in the results - self.assertTrue(pages.filter(id=events_index.id).exists()) + # Check that the events index is in the results + self.assertTrue(pages.filter(id=events_index.id).exists()) - # Check that the event is in the results - self.assertTrue(pages.filter(id=event.id).exists()) + # Check that the event is in the results + self.assertTrue(pages.filter(id=event.id).exists()) def test_merge_queries(self): type_q = Page.objects.type_q(EventPage)