Optimise logic for showing 'Translate' button on the page listing

External translation packages e.g. wagtail-localize can make use of the annotation to get the same performance benefit
pull/12257/head
Sage Abdullah 2024-08-12 16:28:57 +01:00 zatwierdzone przez Matt Westcott
rodzic c5a90d3c7c
commit a99df18f6c
4 zmienionych plików z 31 dodań i 9 usunięć

Wyświetl plik

@ -185,6 +185,10 @@ class IndexView(generic.IndexView):
return super().get(request)
@cached_property
def i18n_enabled(self):
return getattr(settings, "WAGTAIL_I18N_ENABLED", False)
def get_valid_orderings(self):
valid_orderings = super().get_valid_orderings()
@ -230,6 +234,8 @@ class IndexView(generic.IndexView):
# Annotate queryset with various states to be used later for performance optimisations
if getattr(settings, "WAGTAIL_WORKFLOW_ENABLED", True):
pages = pages.prefetch_workflow_states()
if self.i18n_enabled:
pages = pages.annotate_has_untranslated_locale()
pages = pages.annotate_site_root_state().annotate_approved_schedule()
@ -351,7 +357,6 @@ class ExplorableIndexView(IndexView):
self.parent_page = self.parent_page.specific
self.scheduled_page = self.parent_page.get_scheduled_revision_as_object()
self.i18n_enabled = getattr(settings, "WAGTAIL_I18N_ENABLED", False)
if self.i18n_enabled and not self.parent_page.is_root():
self.locale = self.parent_page.locale
self.translations = self.get_translations()

Wyświetl plik

@ -476,7 +476,7 @@ class TestPageListing(WagtailTestUtils, TestCase):
def test_translate_button_displayed(self):
url = reverse("wagtailadmin_explore", args=(self.en_homepage.pk,))
response = self.client.get(url)
with self.assertNumQueries(50):
with self.assertNumQueries(40):
response = self.client.get(url)
soup = self.get_soup(response.content)

Wyświetl plik

@ -48,13 +48,18 @@ def register_submit_translation_permission():
@hooks.register("register_page_listing_more_buttons")
def page_listing_more_buttons(page, user, next_url=None):
if user.has_perm("simple_translation.submit_translation") and not page.is_root():
# If there's at least one locale that we haven't translated into yet,
# show "Translate this page" button
has_locale_to_translate_to = Locale.objects.exclude(
id__in=page.get_translations(inclusive=True).values_list(
"locale_id", flat=True
)
).exists()
if hasattr(page, "_has_untranslated_locale"):
# `_has_untranslated_locale` may be populated by `annotate_has_untranslated_locale`
# on querysets as a performance optimisation
has_locale_to_translate_to = page._has_untranslated_locale
else:
# If there's at least one locale that we haven't translated into yet,
# show "Translate this page" button
has_locale_to_translate_to = Locale.objects.exclude(
id__in=page.get_translations(inclusive=True).values_list(
"locale_id", flat=True
)
).exists()
if has_locale_to_translate_to:
url = reverse("simple_translation:submit_page_translation", args=[page.id])

Wyświetl plik

@ -12,6 +12,7 @@ from django.db.models.functions import Cast, Length, Substr
from django.db.models.query import BaseIterable, ModelIterable
from treebeard.mp_tree import MP_NodeQuerySet
from wagtail.models.i18n import Locale
from wagtail.models.sites import Site
from wagtail.search.queryset import SearchableQuerySetMixin
@ -508,6 +509,17 @@ class PageQuerySet(SearchableQuerySetMixin, SpecificQuerySetMixin, TreeQuerySet)
)
)
def annotate_has_untranslated_locale(self):
return self.annotate(
_has_untranslated_locale=Exists(
Locale.objects.exclude(
id__in=self.model.objects.filter(
translation_key=OuterRef(OuterRef("translation_key"))
).values("locale_id")
)
)
)
class SpecificIterable(BaseIterable):
def __iter__(self):