Sfoglia il codice sorgente

Optimise redirects report

Jake Howard 1 anno fa
parent
commit
bfbd0d5ee2

+ 3 - 2
wagtail/contrib/redirects/models.py

@@ -2,6 +2,7 @@ from urllib.parse import urlparse
 
 from django.db import models
 from django.urls import Resolver404
+from django.utils.functional import cached_property
 from django.utils.translation import gettext_lazy as _
 
 from wagtail.models import Page
@@ -63,10 +64,10 @@ class Redirect(models.Model):
     def __str__(self):
         return self.title
 
-    @property
+    @cached_property
     def link(self):
         if self.redirect_page:
-            page = self.redirect_page.specific
+            page = self.redirect_page.specific_deferred
             base_url = page.url
             if not self.redirect_page_route_path:
                 return base_url

+ 37 - 9
wagtail/contrib/redirects/tests/test_reports_view.py

@@ -1,18 +1,27 @@
 from io import BytesIO
 
-from django.test import TestCase
+from django.test import TestCase, override_settings
 from django.urls import reverse
 from openpyxl import load_workbook
 
 from wagtail.contrib.redirects.models import Redirect
-from wagtail.models import Site
+from wagtail.models import Page, Site
 from wagtail.test.utils import WagtailTestUtils
 
 
+@override_settings(
+    CACHES={"default": {"BACKEND": "django.core.cache.backends.locmem.LocMemCache"}}
+)
 class TestRedirectReport(WagtailTestUtils, TestCase):
+    fixtures = ["test.json"]
+
     def setUp(self):
         self.user = self.login()
 
+        self.page = Page.objects.get(url_path="/home/secret-plans/")
+
+        self.site = Site.objects.first()
+
     def get(self, params={}):
         return self.client.get(reverse("wagtailredirects:report"), params)
 
@@ -42,13 +51,12 @@ class TestRedirectReport(WagtailTestUtils, TestCase):
         self.assertNotContains(response, temp_redirect.old_path)
 
     def test_filtering_by_site(self):
-        site = Site.objects.first()
         site_redirect = Redirect.add_redirect("/cat", "/dog")
-        site_redirect.site = site
+        site_redirect.site = self.site
         site_redirect.save()
         nosite_redirect = Redirect.add_redirect("/from", "/to")
 
-        response = self.get(params={"site": site.pk})
+        response = self.get(params={"site": self.site.pk})
 
         self.assertContains(response, site_redirect.old_path)
         self.assertNotContains(response, nosite_redirect.old_path)
@@ -56,9 +64,13 @@ class TestRedirectReport(WagtailTestUtils, TestCase):
     def test_csv_export(self):
         Redirect.add_redirect("/from", "/to", False)
 
-        response = self.get(params={"export": "csv"})
+        # Session, User, UserProfile, Redirects
+        with self.assertNumQueries(4):
+            response = self.get(params={"export": "csv"})
+
+            csv_data = response.getvalue().decode().split("\n")
+
         self.assertEqual(response.status_code, 200)
-        csv_data = response.getvalue().decode().split("\n")
         csv_header = csv_data[0]
         csv_entries = csv_data[1:]
         csv_entries = csv_entries[:-1]  # Drop empty last line
@@ -70,13 +82,29 @@ class TestRedirectReport(WagtailTestUtils, TestCase):
     def test_xlsx_export(self):
         Redirect.add_redirect("/from", "/to", True)
 
-        response = self.get(params={"export": "xlsx"})
+        # Session, User, UserProfile, Redirects
+        with self.assertNumQueries(4):
+            response = self.get(params={"export": "xlsx"})
+            workbook_data = response.getvalue()
+
         self.assertEqual(response.status_code, 200)
 
-        workbook_data = response.getvalue()
         worksheet = load_workbook(filename=BytesIO(workbook_data))["Sheet1"]
         cell_array = [[cell.value for cell in row] for row in worksheet.rows]
 
         self.assertEqual(cell_array[0], ["From", "To", "Type", "Site"])
         self.assertEqual(len(cell_array), 2)
         self.assertEqual(cell_array[1], ["/from", "/to", "permanent", None])
+
+    def test_num_queries(self):
+        for i in range(3):
+            Redirect.add_redirect(f"/from{i}", "/to", False)
+            Redirect.add_redirect(f"/from-site{i}", "/to", False, site=self.site)
+            Redirect.add_redirect(f"/to-page{i}", self.page, False)
+
+        # Session, User, UserProfile, Redirects, Site
+        with self.assertNumQueries(5):
+            response = self.get(params={"export": "csv"})
+            csv_data = response.getvalue().decode().strip().split("\n")
+
+        self.assertEqual(len(csv_data), 10)

+ 5 - 1
wagtail/contrib/redirects/views.py

@@ -467,4 +467,8 @@ class RedirectsReportView(ReportView):
     }
 
     def get_queryset(self):
-        return models.Redirect.objects.all().order_by("old_path")
+        return (
+            models.Redirect.objects.all()
+            .order_by("old_path")
+            .select_related("site", "redirect_page")
+        )