From 762890b832c4e04bdb65e2624cc4ed4a8f5e5763 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Mon, 10 Jun 2024 17:32:08 +0100 Subject: [PATCH] Fixed #35518 -- Used simpler string operations for converter-less routes --- django/urls/resolvers.py | 35 ++++++++++++++++++++--------- tests/urlpatterns/test_resolvers.py | 7 ++++++ 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py index c667d7f268..cbce7cc5eb 100644 --- a/django/urls/resolvers.py +++ b/django/urls/resolvers.py @@ -322,17 +322,30 @@ class RoutePattern(CheckURLMixin): self.name = name def match(self, path): - match = self.regex.search(path) - if match: - # RoutePattern doesn't allow non-named groups so args are ignored. - kwargs = match.groupdict() - for key, value in kwargs.items(): - converter = self.converters[key] - try: - kwargs[key] = converter.to_python(value) - except ValueError: - return None - return path[match.end() :], (), kwargs + if self.converters: + match = self.regex.search(path) + if match: + # RoutePattern doesn't allow non-named groups so args are ignored. + kwargs = match.groupdict() + for key, value in kwargs.items(): + converter = self.converters[key] + try: + kwargs[key] = converter.to_python(value) + except ValueError: + return None + return path[match.end() :], (), kwargs + else: + # If there are no converters, skip the regex overhead and + # use string operations + if self._is_endpoint: + # If this is an endpoint, the path should be + # exactly the same as the route + if self._route == path: + return "", (), {} + # If this isn't an endpoint, the path should start with the route + elif path.startswith(self._route): + return path.removeprefix(self._route), (), {} + return None def check(self): diff --git a/tests/urlpatterns/test_resolvers.py b/tests/urlpatterns/test_resolvers.py index cb831bbe1c..0a97b92551 100644 --- a/tests/urlpatterns/test_resolvers.py +++ b/tests/urlpatterns/test_resolvers.py @@ -13,6 +13,13 @@ class RoutePatternTests(SimpleTestCase): def test_str(self): self.assertEqual(str(RoutePattern(_("translated/"))), "translated/") + def test_has_converters(self): + self.assertEqual(len(RoutePattern("translated/").converters), 0) + self.assertEqual(len(RoutePattern(_("translated/")).converters), 0) + + self.assertEqual(len(RoutePattern("translated/").converters), 1) + self.assertEqual(len(RoutePattern(_("translated/")).converters), 1) + class ResolverCacheTests(SimpleTestCase): @override_settings(ROOT_URLCONF="urlpatterns.path_urls")