8

I often run into the mistake of using gettext in a context where the actual language is not set yet - instead of using the appropriate gettext_lazy.

Those errors can be difficult to catch - I would like to make them more visible appropriate logging, or possibly even throwing exceptions.

  • Would it be correct, to write a wrapper function that logs an error in the case of get_language() is None?
  • Then of course, one would need to enforce that this wrapper is always used - introducing another subtle easy to make mistake. In general, I suppose monkey-patching could be used, but I'd like to avoid that if possible. The whole dispatch behind django.util.translation seems already relatively complex. Is there a clean way too hook this functionality in there?
Zulan
  • 21,896
  • 6
  • 49
  • 109
  • Here is the link to get the idea [Get the current language in Django](https://stackoverflow.com/questions/3356964/how-can-i-get-the-current-language-in-django) – Arman.shanto Dec 13 '22 at 10:43
  • 1
    if you're willing to wrap and enforce each occurrence of `gettext` why not script a refactoring of `gettext` to `gettext_lazy`? – gregory Dec 14 '22 at 00:45
  • @gregory's suggestion is a good one: `django.utils.translation.gettext = django.utils.translation.gettext_lazy` – Bill Horvath Dec 14 '22 at 20:45
  • @gregory a full discussion on always using `gettext_lazy` over `gettext` would be interesting, but doesn't fit in a comment. And it's not exactly the point of this question - even in that case, I am still reluctant to blindly use monkey-patching. And I even with a refactoring. I still have no means to enforce not using a standard Django function. – Zulan Dec 21 '22 at 12:35

1 Answers1

-1

You can use Django's built-in checks for this. Django provides a check_for_language function that raises a LanguageStoreNotAvailable exception if the language is not set. You can use this function in your code to check for the availability of the language before calling gettext or gettext_lazy.

from django.utils.translation import check_for_language, gettext

def my_function():
    check_for_language()
    return gettext('Hello, world!')

If the language is not set, this will raise a LanguageStoreNotAvailable exception.

Alternatively, you can use Django's gettext_lazy function, which returns a TranslatableString object that will be translated when it is rendered in a template or when force_text is called on it. This avoids the need to call gettext at all and ensures that the translation is not performed until the language is set.

from django.utils.translation import gettext_lazy

def my_function():
    return gettext_lazy('Hello, world!')

This will return a TranslatableString object that can be used in your code or templates, and the translation will be performed when it is rendered.

Overall, it's generally best to use gettext_lazy whenever possible to avoid the need to explicitly check for the availability of the language. This helps to avoid subtle errors and makes your code more robust.

Prithvi Raj
  • 1,611
  • 1
  • 14
  • 33
  • I don't see how this addresses my two specific questions. – Zulan Dec 18 '22 at 21:09
  • 2
    @Zulan, maybe this answer is created using ChatGPT? There are some suspicious similarities between this answer and the other (that just got deleted because of it). – wovano Dec 19 '22 at 13:39