{{{
url(r'^spam/$', 'myapp.views.index', name='myview'),
url(r'^spam/(?P<ham>[\w-]+)/$', 'myapp.views.detail', name='myview'),
url(r'^spam/(?P<ham>[\w-]+)/(?P<eggs>[\w-]+)/$', 'myapp.views.detail',
name='myview'),
}}}
{{{
In [8]: reverse('myview', kwargs={'ham': 'foo', 'eggs': 'bar'})
Out[8]: u'/spam/foo/bar/'
In [9]: reverse('myview', kwargs={'ham': 'foo'})
Out[9]: u'/spam/foo/'
In [10]: reverse('myview')
Out[10]: u'/spam/'
}}}
But this is not documented and it is not clear, whether this is supported
or unsupported behaviour.
It should either be stated clearly that url names should be unique /or/
that it is possible to "overload" url patterns by giving them the same
name when they have a different number of arguments.
--
Ticket URL: <https://code.djangoproject.com/ticket/27367>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: => 0
* needs_tests: => 0
* version: 1.10 => master
* needs_docs: => 0
* type: Uncategorized => Cleanup/optimization
* stage: Unreviewed => Accepted
--
Ticket URL: <https://code.djangoproject.com/ticket/27367#comment:1>
* status: new => assigned
* owner: nobody => Robert Roskam
--
Ticket URL: <https://code.djangoproject.com/ticket/27367#comment:2>
Comment (by Marten Kenbeek):
You can use multiple urls with the same name. These urls will be tried in
reverse order, so starting at the bottom of the list. All arguments passed
to `reverse()` must be used by the pattern to be considered valid. Default
arguments (passed as the `kwargs` parameter to `url()`) may be passed to
`reverse()` as well, but if they are passed, the values must match the
actual arguments to be considered a valid pattern. Consider these
patterns:
{{{
url(r'^spam/$', 'myapp.views.index', name='myview'), # 1
url(r'^spam/(?P<ham>[\w-]+)/$', 'myapp.views.detail', name='myview'),
# 2
url(r'^spam/(?P<ham>[\w-]+)/(?P<eggs>[\w-]+)/$', 'myapp.views.detail',
name='myview'), # 3
url(r'^spam/(?P<ham>[\w-]+)/$', 'myapp.views.detail', kwargs={'eggs':
'bar'} name='myview'), # 4
}}}
Both of these would successfully reverse pattern 4:
{{{
>>> reverse('myview', kwargs={'ham': 'foo'})
'/spam/foo/'
>>> reverse('myview', kwargs={'ham': 'foo', 'eggs': 'bar'})
'/spam/foo/'
}}}
However, this would not match pattern 4, as the value of `eggs` does not
match the original value of `eggs` passed to `url()`. Instead, it will
fall through and match pattern 3:
{{{
>>> reverse('myview', kwargs={'ham': 'foo', 'eggs': 'baz'})
'/spam/foo/baz/'
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/27367#comment:3>
Comment (by Robert Roskam):
Not sure if the behavior was intended or not based on available
documentation. Rather than making a change, I've put tests around how it
functions and updated documentation. You can see my changes here:
https://github.com/django/django/pull/7417/files
--
Ticket URL: <https://code.djangoproject.com/ticket/27367#comment:4>
* has_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/27367#comment:5>
Comment (by Reinout van Rees):
I've [https://github.com/django/django/pull/7417#pullrequestreview-7311486
reviewed the pull request]. The test looks handy.
I'm not sure about the text. The text might have to be moved somewhere
else.
--
Ticket URL: <https://code.djangoproject.com/ticket/27367#comment:6>
Comment (by Reinout van Rees):
Oh, I retract my comment about it having to move somewhere else :-)
There is no further page where there's some urls/reverse() explanation:
the https://docs.djangoproject.com/en/1.10/topics/http/urls/ page is
**huge**. So the text belongs there. (It might be worthwhile to split up
the huge page at another point in time, but that's outside of the scope of
this ticket).
--
Ticket URL: <https://code.djangoproject.com/ticket/27367#comment:7>
* needs_better_patch: 0 => 1
Comment:
I've added a pull request to Robert's branch with my suggested changes in
there: https://github.com/raiderrobert/django/pull/1
(I've checked the "patch needs improvement" checkbox just for clarity,
feel free to uncheck it if my changes aren't handy).
--
Ticket URL: <https://code.djangoproject.com/ticket/27367#comment:8>
* cc: reinout@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/27367#comment:9>
* needs_better_patch: 1 => 0
* stage: Accepted => Ready for checkin
Comment:
I'd say it is ready for checkin now! Nice to have some documentation for
this. I was surprised that it was under-documented :-) Thanks, Robert!
(My PR for the original PR has been merged).
--
Ticket URL: <https://code.djangoproject.com/ticket/27367#comment:10>
* needs_better_patch: 0 => 1
* stage: Ready for checkin => Accepted
Comment:
The content is looking good and I left some comments for further
improvement.
--
Ticket URL: <https://code.djangoproject.com/ticket/27367#comment:11>
* needs_better_patch: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/27367#comment:12>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"98bcc5d81bca578f3a5b4d47907ba4ac40446887" 98bcc5d8]:
{{{
#!CommitTicketReference repository=""
revision="98bcc5d81bca578f3a5b4d47907ba4ac40446887"
Fixed #27367 -- Doc'd and tested reversing of URLs with the same name.
Thanks Reinout van Rees for contributing to the patch.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/27367#comment:13>
Comment (by Tim Graham <timograham@…>):
In [changeset:"c0916144502b2b9d75b75ce6b01148aaa3dcaf68" c0916144]:
{{{
#!CommitTicketReference repository=""
revision="c0916144502b2b9d75b75ce6b01148aaa3dcaf68"
[1.11.x] Fixed #27367 -- Doc'd and tested reversing of URLs with the same
name.
Thanks Reinout van Rees for contributing to the patch.
Backport of 98bcc5d81bca578f3a5b4d47907ba4ac40446887 from master
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/27367#comment:14>