Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 57 additions & 2 deletions wagtail_localize/tests/test_translations_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@
from wagtail.models import Locale, Page
from wagtail.test.utils import WagtailTestUtils

from wagtail_localize.models import Translation, TranslationSource
from wagtail_localize.models import (
String,
StringTranslation,
Translation,
TranslationContext,
TranslationSource,
)
from wagtail_localize.test.models import TestSnippet

from .utils import make_test_page
Expand Down Expand Up @@ -40,7 +46,10 @@ def setUp(self):

self.en_blog_index = make_test_page(self.en_homepage, title="Blog", slug="blog")
self.en_blog_post = make_test_page(
self.en_blog_index, title="Blog post", slug="blog-post"
self.en_blog_index,
title="Blog post",
slug="blog-post",
test_charfield="Test content",
)

self.snippet_translation = Translation.objects.create(
Expand All @@ -67,6 +76,10 @@ def setUp(self):
source=TranslationSource.get_or_create_from_instance(self.en_blog_post)[0],
target_locale=self.fr_locale,
)
self.test_charfield_context = TranslationContext.objects.get(
path="test_charfield"
)
self.test_content_string = String.objects.get(data="Test content")

def test_get_empty_report(self):
Translation.objects.all().delete()
Expand Down Expand Up @@ -192,3 +205,45 @@ def test_locale_filters_get_proper_choices(self):
("es", "Spanish"),
],
)

def test_filter_by_waiting_for_translation_true(self):
StringTranslation.objects.create(
translation_of=self.test_content_string,
context=self.test_charfield_context,
locale=self.fr_locale,
data="Contenu de test",
)
response = self.client.get(
reverse("wagtail_localize:translations_report")
+ "?waiting_for_translation=true"
)

# These pages don't have any translations, so they should be listed
self.assertIn(self.snippet_translation, response.context["object_list"])
self.assertIn(self.homepage_translation, response.context["object_list"])
self.assertIn(self.de_homepage_translation, response.context["object_list"])
# Blog index page has no translatable strings, so should not be included
self.assertNotIn(self.blog_index_translation, response.context["object_list"])
# Translation is complete for this page, so should not be included
self.assertNotIn(self.blog_post_translation, response.context["object_list"])

def test_filter_by_waiting_for_translation_false(self):
StringTranslation.objects.create(
translation_of=self.test_content_string,
context=self.test_charfield_context,
locale=self.fr_locale,
data="Contenu de test",
)
response = self.client.get(
reverse("wagtail_localize:translations_report")
+ "?waiting_for_translation=false"
)

# These pages don't have any translations, so they should not be listed
self.assertNotIn(self.snippet_translation, response.context["object_list"])
self.assertNotIn(self.homepage_translation, response.context["object_list"])
self.assertNotIn(self.de_homepage_translation, response.context["object_list"])
# Blog index page has no translatable strings, so should be included
self.assertIn(self.blog_index_translation, response.context["object_list"])
# Translation is complete for this page, so should be included
self.assertIn(self.blog_post_translation, response.context["object_list"])
36 changes: 33 additions & 3 deletions wagtail_localize/views/report.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import django_filters

from django.contrib.contenttypes.models import ContentType
from django.db.models import Exists, OuterRef
from django.utils.text import capfirst
from django.utils.translation import gettext_lazy
from django_filters.constants import EMPTY_VALUES
Expand All @@ -12,7 +13,7 @@
from wagtail.coreutils import get_content_languages
from wagtail.models import get_translatable_models

from wagtail_localize.models import Translation
from wagtail_localize.models import StringSegment, StringTranslation, Translation


class SourceTitleFilter(django_filters.CharFilter):
Expand Down Expand Up @@ -130,10 +131,19 @@ class TranslationsReportFilterSet(WagtailFilterSet):
null_label=gettext_lazy("All"),
null_value="all",
)
waiting_for_translation = django_filters.BooleanFilter(
label=gettext_lazy("Waiting for translations"),
)

class Meta:
model = Translation
fields = ["content_type", "source_title", "source_locale", "target_locale"]
fields = [
"content_type",
"source_title",
"source_locale",
"target_locale",
"waiting_for_translation",
]


def _adapt_wagtail_report_attributes(cls):
Expand Down Expand Up @@ -175,4 +185,24 @@ class TranslationsReportView(ReportView):
filterset_class = TranslationsReportFilterSet

def get_queryset(self):
return Translation.objects.all()
return Translation.objects.annotate(
# Check to see if there is at least one string segment that is not
# translated.
waiting_for_translation=Exists(
StringSegment.objects.filter(source_id=OuterRef("source_id"))
.annotate(
# Annotate here just to filter in the next subquery, as Django
# doesn't have support for nested OuterRefs.
_target_locale_id=OuterRef("target_locale_id"),
is_translated=Exists(
StringTranslation.objects.filter(
translation_of_id=OuterRef("string_id"),
context_id=OuterRef("context_id"),
locale_id=OuterRef("_target_locale_id"),
has_error=False,
)
),
)
.filter(is_translated=False)
)
)