Opened 5 months ago

Last modified 5 months ago

#36279 assigned Bug

Maybe a little Bug in `django.urls.base.translate_url` — at Initial Version

Reported by: Rami Boutassghount Owned by:
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

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"), the redirect works once 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 (0)

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