İçeriğe geç

Django Translation Testing

Giriş.

Merhabalar.

Django bildiğiniz üzere yerleşik olarak bir localization ve internationalization altyapısına sahip.

Bu yapı ile kolayca uygualamalarımızı çoklu dil desteğine sahip ve yerel metriklere göre formatlanmış bir hale getirebilmekteyiz.

Geçenlerde ekibimdeki bir frontend geliştiricisi arkadaşın yardım çağrısına kulak verirken karşılaştığım bir problemden bahsedeceğim. Geliştirmesi tamamlanan bir endpointten atılan mail templateinde tüm çeviriler doğru çalışırken, mail başlığı bir türlü istenen çeviride gelmiyordu.

Açıkcası ilk defa böyle ilginç bir durumla karşılaşmıştım ve bir kaç deneme yaptıktan sonra belli başlı çıkarımlara ulaştım. Frontendci arkadaşa çözümü ilettim herkes mutluydu. Fakat başka birileri ileride saç baş yolmasın diye bu tarz bir durumda nasıl bir çözüm yolu uyguladığımı bu blog altında kayıt altına almak istedim. Hikaye kısmını atlayacak olursak; 🙂

Bazı durumlarda, ilgili .po dosyasında yapmış olduğunuz değişiklikler bir şekilde ezilebilir ve çevirdiğinizi zannettiğiniz söz öbeği canlıda bambaşka görünebilir 🙂

Bu problemin, bir kaç temel açıklaması bulunmaktadır.

  • Uygulamanız içinde birden fazla locale path bulunması. Bu pathlerde yaşayan .po dosyalarında farklı çevirilerin bulunması ve çeviri aranırken istenmeyen çevirinin önceliklendirmesi.
  • Çevirinin bir şekilde .po dosyasına eklenememesi ve 3.parti bir uygulama tarafından tanımlanan çevirinin kullanılması.

Neyse ki böyle bir uç nokta ile karşılaştığımızda, ilgili çevirinin kullanıldığı kompleks adımları reproduce edip sorunu bulmaya çalışmaktansa çok daha kolay bir çözüm yolu bulunuyor.

Test yazmak!

Basit bir kurgu.

2 dilde sunduğumuz bir uygulamamız olsun. İngilizce ve Ukraynaca. Konfigürasyon aşağıdaki gibi.

LANGUAGES = [
  ('ua', 'Ukraine'),
  ('en', 'English')
]
LOCALE_PATHS = [
    BASE_DIR / "locales",
]

Ve çeviriye ihtyiaç olan bir fazlasıyla işlevsel(!) view yazalım.

from django.http import JsonResponse
from django.utils.translation import gettext as _
def translate_test(request):
    return JsonResponse({"message": _("Hello wild world.")})

.po dosyasını ua için oluşturalım, aşağıdaki gibi düzenleyelim ve compile edelim.

msgid "Hello wild world."
msgstr "Привіт, дикий світ."

Test yazmak.

Yapılan çeviri yerine beklenmedik çıktıların alındığı durumlarda, ilgili çeviri stringi için test yazmak en mantıklı ve hızlı sonuç veren yaklaşım olacaktır.

Ayrıca test yazarak göz atacağınız problemli çevirinin kullanıldığı kompleks adımları tekrar etmekten kendinizi soyutlamış olursunuz.

Django’nun bu ihtiyacı karşılamak ve uygulama dilini dinamik yönetebilmeniz için yardımcı fonksiyonları bulunur.

Testler.

from django.test import TestCase
from django.urls import reverse
from django.utils import translation
class TranslationTestCase(TestCase):
    def setUp(self):
        self.url = reverse("test_translate")
    def test_translation_on_with_gettext(self):
        with translation.override("ua"):
            self.assertEqual(
                translation.gettext("Hello wild world."), "Привіт, дикий світ."
            )
    def test_translation_with_header(self):
        res = self.client.get(self.url, HTTP_ACCEPT_LANGUAGE="ua")
        request_accept_language = translation.get_language_from_request(
            res.wsgi_request
        )
        self.assertEqual(request_accept_language, "ua")
        self.assertEqual(res.json()["message"], "Привіт, дикий світ.")
    def test_translation_with_active(self):
        translation.activate("ua")
        self.assertEqual(
            translation.gettext("Hello wild world."), "Привіт, дикий світ."
        )

Bir çok yardımcı metod ve yol bulunmakta. Hepsini örnekleyebilmek adına birer test ekledim.

Çeviri bir view sonucunda dönüyorsa ilgili urle istek atabilir, request nesnesi üzerinden dil kontrolünü sağlayabilir ve sonuca göz atabilirsiniz.

Fakat, çeviri bir template içinde bulunuyorsa doğrudan override ve activate fonksiyonlarını kullanarak shell üzerinden çeviri dilini aktif hale getirip gettext ile karşılığını kontrol edebilirsiniz.

Eğer beklenen çıktı override ve activate fonksiyonları yardımıyla alınabiliyor ama canlıda alınamıyorsa, projedeki localization ayarlarınızı ya da senaryonuzda celery taski bulunuyorsa dilin request nesnesi üzerinden taske doğru geçirilip geçirilemediğini kontrol etmenizi öneririm.

Görüşmek üzere!

Bu yazıya ön ayak olan frontend geliştiricisi arkadaşım Sümeyye’ye selamlar! 😄

 

 

Tarih:Blog

Tek Yorum

  1. Cihad GÜNDOĞDUD Cihad GÜNDOĞDUD

    Tabii bu po dosyalarına yeni çevirileri dahil etmek için komut satırından önce
    python manage.py makemessages -l tr
    yazarak gettext fonksiyonu ile çağırdığımız string ifadeleri po dosyasına dahil ediyoruz(Örnekte tr ama istediğimiz dili seçebiliriz) daha sonra
    python manage.py compilemessages yazarak mo dosyasına derlenmesini sağlıyoruz. Değişiklilerin uygulamaya yansıması içinse yeniden başlatmak gerekebilir.

    Tebrikler güzel yazı.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.

Göster
Gizle