#26431 closed Bug (fixed)
translate_url() creates an incorrect URL when optional named groups are missing in the URL pattern
Reported by: | EugeneM | Owned by: | Daniel Rios |
---|---|---|---|
Component: | Core (URLs) | Version: | dev |
Severity: | Normal | Keywords: | translate_url |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | yes | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
There is a problem when translating urls with absent 'optional' arguments
(it's seen in test case of the patch)
Attachments (2)
Change History (13)
by , 9 years ago
Attachment: | patch-stable-1.9.txt added |
---|
by , 9 years ago
Attachment: | patch-master.txt added |
---|
comment:1 by , 9 years ago
Patch needs improvement: | set |
---|---|
Summary: | django.core.urlresolvers.translate_url fix → translate_url() creates an incorrect URL when optional named groups are missing in the URL pattern |
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 9 years ago
The issue here is that resolve()
will return None
for any optional capture groups that aren't captured, but reverse()
will use force_text()
and convert it to the literal string 'None'
. This causes an asymmetry between resolve()
and reverse()
.
I think it's a better idea to treat this asymmetry as a bug, and solve it within reverse()
. We would discard any arguments that are None
. Incidentally this will allow for cleaner code when you don't know if an optional parameter is set when you call reverse()
or the {% url %}
template tag:
{% if obj.might_be_none != None %} {% url 'my_view' obj.might_be_none %} {% else %} {% url 'my_view' %} {% endif %}
vs.
{% url 'my_view' obj.might_be_none %}
I think that's a reasonably common usecase, so it would be nice to support this cleaner syntax. Non-existent template variables will still pass an empty string rather than None
, so this won't hide any typos in your template variable names.
comment:3 by , 6 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:4 by , 6 years ago
This also affects the set_language function.
When changing language on a page with an URL pattern containing an optional group, the empty optional part is set to none and translating the page leads to a 404.
The bug on translation did not exist back in 1.8, not sure when it was introduced. I'm on 2.2.
The best way to resolve both issues would be to patch directly _reverse_with_prefix in django.urls.resolvers.
comment:6 by , 6 years ago
Needs tests: | set |
---|
Could you please provide the patch as a pull request against master? Unless this is a regression, it probably doesn't qualify for a backport to 1.9 (see our supported versions policy). Please check the patch on Python 3 as well (
dict.iteritems()
doesn't exist there).