Opened 17 months ago
Last modified 3 days 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: | Django Sprints |
|---|---|---|---|
| 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 )
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 (9)
comment:1 by , 17 months ago
| Component: | Uncategorized → Core (URLs) |
|---|---|
| Type: | Uncategorized → Bug |
follow-up: 7 comment:2 by , 17 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: | Unreviewed → Accepted |
comment:3 by , 17 months ago
| Description: | modified (diff) |
|---|
comment:4 by , 17 months ago
| Owner: | set to |
|---|---|
| Status: | new → assigned |
comment:5 by , 17 months ago
| Has patch: | set |
|---|
comment:6 by , 17 months ago
| Patch needs improvement: | set |
|---|
comment:7 by , 16 months ago
Hi maintainers,
I've been testing the URL translation functionality and encountered several test failures. Here's what I found:
Test Failures:
- URL prefix tests fail with language code mismatches (en vs nl)
- URL translation tests fail with incorrect path translations
- 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:
- How to properly handle language codes in URLs
- The correct way to translate URL paths
- Fixing the 404 errors for translated paths
Thanks for your help!
comment:8 by , 9 months ago
Hello Maintainers, I can see this ticket has been idle since long. Should I give it a try as my first contribution?
comment:9 by , 3 days ago
| Owner: | changed from to |
|---|
Assigning to Django Sprints for to reserve for an upcoming sprint. DjangoCon US ends August 28, this is available for someone else to pick up on the 29th.
Ahmed Nassar, if you'd like to continue to work on this please re-assign this to yourself.
Thank you, replicated
tests/i18n/patterns/tests.py
tests/i18n/patterns/urls/default.py