Opened 5 months ago

Last modified 5 months ago

#36279 assigned Bug

translatable path without a name attribute does not translate in django.urls.base.translate_url

Reported by: Rami Boutassghount Owned by: Ahmed Nassar
Component: Core (URLs) Version: 5.1
Severity: Normal Keywords: set_language, i18n, translate_url, url, translation, url path
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description (last modified by Rami Boutassghount)

Dear all,

I was trying to mark a URL path for translation in the urlpatterns list object and I found an unexpected behavior when I try to change the language via set_language view (django.view.i18n.views.set_language).

A path must have a name attribute (for instance name="translate-url") in order to make the redirect work after a language change (set_language view). Otherwise, we get 404. This behavior may be a little bug in django (django.urls.base.translate_url), since the framework does not force the developer to use name in the url paths.

To put simple, I will explain it with code.

  • This will work (by 'work' I mean that we will get a translated url in the browser):
path(_('translate-this-url'), translate_this_url_view, name="translate-url"),
  • This will not work (we will get a 404 error)
path(_('translate-this-url'), translate_this_url_view,),

I dig a bit in the code and I found out that the function django.urls.base.translate_url may be missing a check (verify if the url_name attribute of the matched urlpath object is None or not). Check the following snippet:

# django.urls.base.translate_url
def translate_url(url, lang_code):
    parsed = urlsplit(url)
    try:
        # URL may be encoded.
        match = resolve(unquote(parsed.path))
    except Resolver404:
        pass
    else:
        
        # TODO: here we should do something (if url_name is None: do something else)
        
        to_be_reversed = (
            "%s:%s" % (match.namespace, match.url_name)
            if match.namespace
            else match.url_name
        )

        with override(lang_code):
            try:
                url = reverse(to_be_reversed, args=match.args, kwargs=match.kwargs)
            except NoReverseMatch:
                pass
            else:
                url = urlunsplit(
                    (parsed.scheme, parsed.netloc, url, parsed.query, parsed.fragment)
                )
    return url

Many thanks for having a look a the ticket!

Change History (7)

comment:1 by Rami Boutassghount, 5 months ago

Component: UncategorizedCore (URLs)
Type: UncategorizedBug

comment:2 by Sarah Boyce, 5 months ago

Easy pickings: unset
Summary: Maybe a little Bug in `django.urls.base.translate_url`translatable path without a name attribute does not translate in django.urls.base.translate_url
Triage Stage: UnreviewedAccepted

Thank you, replicated

  • tests/i18n/patterns/tests.py

    a b class URLTranslationTests(URLTestCaseBase):  
    186186                translate_url("/en/account/register-as-path/", "nl"),
    187187                "/nl/profiel/registreren-als-pad/",
    188188            )
     189            self.assertEqual(
     190                translate_url("/en/register-as-path/", "nl"),
     191                "/nl/registreren-als-pad/",
     192            )
    189193            self.assertEqual(translation.get_language(), "en")
    190194            # re_path() URL with parameters.
    191195            self.assertEqual(
  • tests/i18n/patterns/urls/default.py

    diff --git a/tests/i18n/patterns/urls/default.py b/tests/i18n/patterns/urls/default.py
    index 090b92eeca..0563394013 100644
    a b urlpatterns += i18n_patterns(  
    3535    re_path(
    3636        _(r"^account/"), include("i18n.patterns.urls.namespace", namespace="account")
    3737    ),
     38    path(_("register-as-path/"), view),
    3839)

comment:3 by Rami Boutassghount, 5 months ago

Description: modified (diff)

comment:4 by Ahmed Nassar, 5 months ago

Owner: set to Ahmed Nassar
Status: newassigned

comment:5 by Ahmed Nassar, 5 months ago

Has patch: set

comment:6 by Sarah Boyce, 5 months ago

Patch needs improvement: set

in reply to:  2 comment:7 by Ahmed Nassar, 5 months ago

Hi maintainers,

I've been testing the URL translation functionality and encountered several test failures. Here's what I found:

Test Failures:

  1. URL prefix tests fail with language code mismatches (en vs nl)
  2. URL translation tests fail with incorrect path translations
  3. Response tests return 404 instead of 200 for translated paths

Running: python runtests.py i18n.patterns.tests

Sample errors:

  • '/en/prefixed/' != '/nl/prefixed/'
  • '/translated/' != '/vertaald/'
  • '/en/users/' != '/nl/gebruikers/'
  • 404 status code instead of 200 for Dutch and Portuguese URLs

Could you please help with:

  1. How to properly handle language codes in URLs
  2. The correct way to translate URL paths
  3. Fixing the 404 errors for translated paths

Thanks for your help!

Note: See TracTickets for help on using tickets.
Back to Top