#29775: custom url converters are not picked up on reverse when part of included patterns with namespace -------------------------------------+------------------------------------- Reporter: Eric Brandwein | Owner: nobody Type: Bug | Status: closed Component: Core (URLs) | Version: 2.1 Severity: Normal | Resolution: needsinfo Keywords: converter, | Triage Stage: namespace, reverse, include | Unreviewed Has patch: 0 | Needs documentation: 0 Needs tests: 0 | Patch needs improvement: 0 Easy pickings: 0 | UI/UX: 0 -------------------------------------+-------------------------------------
Comment (by Eric Brandwein): Hi Carlton, the issue happens when you have some URL with a custom converter, in which you are including other URLs without passing a namespace to `include()`. These other URLs, in turn, include another list of URLs, this time with a namespace. The tests you mention seem to just test namespacing from the first level of URLs, instead of from just the second, like in the example I gave. It would seem that when using instance namespaces, the converters are only searched from one `include()` upwards, instead of from all the `include()` "tree". I made a test for it here: https://github.com/ericbrandwein/django/commit/de60d4f200ef08573f92942f0269a4b22a878290. The diff is: {{{ diff --git a/tests/urlpatterns/path_base64_urls.py b/tests/urlpatterns/path_base64_urls.py index 9b69f929fe..c9b4f6f9ca 100644 --- a/tests/urlpatterns/path_base64_urls.py +++ b/tests/urlpatterns/path_base64_urls.py @@ -4,8 +4,14 @@ from . import converters, views register_converter(converters.Base64Converter, 'base64') +subsubpatterns = [ + path('<base64:last_value>/', views.empty_view, name='subsubpattern- base64'), +] + subpatterns = [ path('<base64:value>/', views.empty_view, name='subpattern-base64'), + path('<base64:value>/', + include((subsubpatterns, 'second-layer-namespaced-base64'), 'instance-ns-base64')), ] urlpatterns = [ diff --git a/tests/urlpatterns/tests.py b/tests/urlpatterns/tests.py index b3d97ec5b9..8483d225d5 100644 --- a/tests/urlpatterns/tests.py +++ b/tests/urlpatterns/tests.py @@ -70,6 +70,17 @@ class SimplifiedURLTests(SimpleTestCase): url = reverse(url_name, kwargs=kwargs) self.assertEqual(url, expected) + @override_settings(ROOT_URLCONF='urlpatterns.path_base64_urls') + def test_converter_reverse_with_second_layer_instance_namespace(self): + expected = '/base64/aGVsbG8=/namespaced/d29ybGQ=/d29ybGQ=/' + url_name = 'subsubpattern-base64' + instance_ns = 'instance-ns-base64' + kwargs = included_kwargs + kwargs['last_value'] = b'world' + url_name = '%s:%s' % (instance_ns, url_name) + url = reverse(url_name, kwargs=kwargs) + self.assertEqual(url, expected) + def test_path_inclusion_is_matchable(self): match = resolve('/included_urls/extra/something/') self.assertEqual(match.url_name, 'inner-extra') }}} Maybe this test is somewhat ugly, but it shows the bug. It fails with this message: {{{ django.urls.exceptions.NoReverseMatch: Reverse for 'subsubpattern-base64' with keyword arguments '{'base': b'hello', 'value': b'world', 'last_value': b'world'}' not found. 1 pattern(s) tried: ['base64/(?P<base>[a-zA-Z0-9+/]*={0,2})/subpatterns/(?P<value>[a-zA-Z0-9+/]*={0,2})/(?P<last_value>[a-zA-Z0-9+/]*={0,2})/$'] }}} Which means that the converter's `regex` is being used, but not its `to_url` function. -- Ticket URL: <https://code.djangoproject.com/ticket/29775#comment:3> 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 django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/071.c6342e837ee67f262dda31255e3ce4d9%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.