How do I manually ask Django to translate a string (which I know there is a translation for)?

I just implemented translations for my learning-to-code-side-project, and it works great! I also use django-modeltranslation for models, and no problems there either.

As a finishing touch I wanted to create a view that changes the language. It should take a single keyword argument – the language_code of the desired language, e.g. “en-us”, “de”, “nb” and so on, and also should accept the GET parameter next, which I then forward the user to after the language settings have been updated. E.g.:

http://127.0.0.1:8000/en-us/change-language/nb/?next=/en-us/dashboard/

In this example url /en-us/ is the current language, /change-language/ is the location of the change-language-view (so to speak), /nb/ is the desired language, and ?next=/en-us/dashboard/ is the current url in the current language (and thus where users will be redirected after having their language changed, and after the url have been translated to a new language, e.g. “/nb/kontrollpanel/”)

I made the URL-translations work with resolve and reverse as seen below:

def change_language_view(request, **kwargs):
    #get and validate the language user is trying to change to
    language_code = kwargs.get('language_code', None)
    try:
        assert [lang[0] for lang in settings.LANGUAGES if lang[0] == language_code], _("%(selected_languages)s not in %(settings_languages)s"%{language_code, settings.LANGUAGES})
    except (AssertionError, TypeError) as err:
        raise Http404(_("Couldn't find that language: "))

    #get the next path, if any
    #create fallback values
    next_view = 'index'
    next_args = None
    next_kwargs = None
    #try to get and resolve from urls next-argument
    next_path = request.GET.get('next', None)
    try:
        if next_path is not None:
            next_view, next_args, next_kwargs = resolve(next_path)
    except Exception as err:
            pass

    #activate translation for the intended language
    translation.activate(language_code)

    #make a new next_url, now that we are in the new language
    next_url = reverse(next_view, args=next_args, kwargs=next_kwargs)

    #make response, attach cookie, and return it
    response = HttpResponseRedirect(next_url)
    response.set_cookie(settings.LANGUAGE_COOKIE_NAME, language_code)
    return response

It works beautifully, except for one URL:

path(_('product-details/<uidb64>/<product_name>/'), ...

This url takes two arguments, the first (uidb64) is unproblematic, as it’s not translated, the second (product_name) is the a product name, which sadly, is not translated when making the new URL. I understand why this is, it’s because to Django it’s just a random string retrieved from the database. What i wish to do is add something like:

if 'product_name' in next_kwargs:
    force_django_to_translate(next_kwargs['product_name']) #I know that product_name is translated if Django would just look

So to be very clear, I want the url:

/en-us/product-details/Mq/my-awesome-product/

to become:

/nb/produktdetaljer/Mq/mitt-fantastiske-produkt/

but right now it’s becoming:

/nb/produktdetaljer/Mq/my-awesome-product/

And the translation is already in place, I just need Django to say “Hey, I should probably translate that”.

Any thougts?

asked 12 hours ago
vetleenvetleen

434 bronze badges

Latest posts