瀏覽代碼

Fixed #29744 -- Fixed caching of URLResolver for a default URLconf.

get_resolver() for a default URLconf (passing no argument) and for
settings.ROOT_URLCONF should return the same cached object.
Benjamin Woodruff 5 年之前
父節點
當前提交
54dcfbc367
共有 3 個文件被更改,包括 18 次插入4 次删除
  1. 2 2
      django/urls/base.py
  2. 5 1
      django/urls/resolvers.py
  3. 11 1
      tests/urlpatterns/test_resolvers.py

+ 2 - 2
django/urls/base.py

@@ -7,7 +7,7 @@ from django.utils.functional import lazy
 from django.utils.translation import override
 
 from .exceptions import NoReverseMatch, Resolver404
-from .resolvers import get_ns_resolver, get_resolver
+from .resolvers import _get_cached_resolver, get_ns_resolver, get_resolver
 from .utils import get_callable
 
 # SCRIPT_NAME prefixes for each thread are stored here. If there's no entry for
@@ -92,7 +92,7 @@ reverse_lazy = lazy(reverse, str)
 
 def clear_url_caches():
     get_callable.cache_clear()
-    get_resolver.cache_clear()
+    _get_cached_resolver.cache_clear()
     get_ns_resolver.cache_clear()
 
 

+ 5 - 1
django/urls/resolvers.py

@@ -63,10 +63,14 @@ class ResolverMatch:
         )
 
 
-@functools.lru_cache(maxsize=None)
 def get_resolver(urlconf=None):
     if urlconf is None:
         urlconf = settings.ROOT_URLCONF
+    return _get_cached_resolver(urlconf)
+
+
+@functools.lru_cache(maxsize=None)
+def _get_cached_resolver(urlconf=None):
     return URLResolver(RegexPattern(r'^/'), urlconf)
 
 

+ 11 - 1
tests/urlpatterns/test_resolvers.py

@@ -1,5 +1,6 @@
 from django.test import SimpleTestCase
-from django.urls.resolvers import RegexPattern, RoutePattern
+from django.test.utils import override_settings
+from django.urls.resolvers import RegexPattern, RoutePattern, get_resolver
 from django.utils.translation import gettext_lazy as _
 
 
@@ -13,3 +14,12 @@ class RoutePatternTests(SimpleTestCase):
 
     def test_str(self):
         self.assertEqual(str(RoutePattern(_('translated/'))), 'translated/')
+
+
+class ResolverCacheTests(SimpleTestCase):
+    @override_settings(ROOT_URLCONF='urlpatterns.path_urls')
+    def test_resolver_cache_default__root_urlconf(self):
+        # resolver for a default URLconf (passing no argument) and for the
+        # settings.ROOT_URLCONF is the same cached object.
+        self.assertIs(get_resolver(), get_resolver('urlpatterns.path_urls'))
+        self.assertIsNot(get_resolver(), get_resolver('urlpatterns.path_dynamic_urls'))