#29415: custom url converters are not picked up on reverse when part of included
patterns
---------------------------------------+------------------------
Reporter: Xaroth | Owner: nobody
Type: Bug | Status: new
Component: Core (URLs) | Version: 2.1
Severity: Normal | Keywords:
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
---------------------------------------+------------------------
Under normal circumstances, url converters `to_url` methods are called
when reversing a url, however, this behavior is inconsistent when used
with included sub-patterns
To demonstrate:
{{{
from django.urls import path, include, register_converter
from django.urls.converters import StringConverter
class ReverseConverter(StringConverter):
def to_python(self, value):
"""More complex use cases are possible, but this simple case of
reversing the string already shows it in effect"""
return value[::-1]
def to_url(self, obj):
"""More complex use cases are possible, but this simple case of
reversing the string already shows it in effect"""
return obj[::-1]
register_converter(ReverseConverter, 'rstr')
def noop(request): # A noop since we are merely testing reverse()
pass
# Patterns in here will
included_patterns = [
path('', noop, name='fail-case-1'),
path('<rstr:itemb>', noop, name='fail-case-2'),
]
direct_patterns = [
path('<rstr:item>', noop, name='success-case-1'),
path('<rstr:item>/<rstr:itemb>', noop, name='success-case-2'),
]
urlpatterns = [
path('<rstr:item>/', include(included_patterns)),
path('', include(direct_patterns)),
path('<rstr:item>', noop, name='success-case-3'),
]
}}}
When running the following test, both patterns -should- return the same
URL, however, they do not:
{{{
In [1]: from django.urls import reverse
In [2]: reverse('success-case-1', kwargs={'item': 'abc123'}) # Expected:
'/321cba'
Out[2]: '/321cba'
In [3]: reverse('success-case-2', kwargs={'item': 'abc123', 'itemb':
'xyz789'}) # Expected: '/321cba/987zyx'
Out[3]: '/321cba/987zyx'
In [4]: reverse('success-case-3', kwargs={'item': 'abc123'}) # Expected:
'/321cba'
Out[4]: '/321cba'
In [5]: reverse('fail-case-1', kwargs={'item': 'abc123'}) # Expected:
'/321cba/'
Out[5]: '/abc123/'
In [6]: reverse('fail-case-2', kwargs={'item': 'abc123', 'itemb':
'xyz789'}) # Expected: '/321cba/987zyx'
Out[6]: '/abc123/987zyx'
}}}
Note that at the last case, `item` is not reversed, where `itemb` is.
The main culprit (I think) is that when populating the URLResolver's
reverse_dict, included sub-resolvers are not updated with the converters
of the resolver that includes them, as such, they skip the converters for
the base resolver when reversing the URL.
I have confirmed this inconsistency in versions 2.0 through 2.0.5, 2.1a1
as well as master (@9f6188b).
--
Ticket URL: <https://code.djangoproject.com/ticket/29415>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/049.b2bfc22436fe8d509a621cc0ab2eb21c%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.