summaryrefslogtreecommitdiff
path: root/django/contrib/admindocs/utils.py
diff options
context:
space:
mode:
authorAlokik Vijay <alokik.roe@gmail.com>2022-05-17 09:46:26 +0200
committerCarlton Gibson <carlton@noumenal.es>2022-05-17 10:50:09 +0200
commit7f3cfaa12b28d15c0ca78bb692bfd6e59d17bff1 (patch)
treeb9da3508b15e3bbbb42332f282ce8e0075f5d7e0 /django/contrib/admindocs/utils.py
parent2a5d2eefc751be012fdebd75d8177c42bf5a76fc (diff)
downloaddjango-7f3cfaa12b28d15c0ca78bb692bfd6e59d17bff1.tar.gz
Fixed #32565 -- Moved internal URLResolver view-strings mapping to admindocs.
Moved the functionality of URLResolver._is_callback(), URLResolver._callback_strs, URLPattern.lookup_str() to django.contrib.admindocs.
Diffstat (limited to 'django/contrib/admindocs/utils.py')
-rw-r--r--django/contrib/admindocs/utils.py44
1 files changed, 44 insertions, 0 deletions
diff --git a/django/contrib/admindocs/utils.py b/django/contrib/admindocs/utils.py
index 6edff502ec..a18dbe12cd 100644
--- a/django/contrib/admindocs/utils.py
+++ b/django/contrib/admindocs/utils.py
@@ -1,11 +1,15 @@
"Misc. utility functions/classes for admin documentation generator."
+import functools
import re
from email.errors import HeaderParseError
from email.parser import HeaderParser
from inspect import cleandoc
+from asgiref.local import Local
+
from django.urls import reverse
+from django.urls.resolvers import URLPattern
from django.utils.regex_helper import _lazy_re_compile
from django.utils.safestring import mark_safe
@@ -239,3 +243,43 @@ def remove_non_capturing_groups(pattern):
final_pattern += pattern[prev_end:start]
prev_end = end
return final_pattern + pattern[prev_end:]
+
+
+# Callback strings are cached in a dictionary for every urlconf.
+# The active calback_strs are stored by thread id to make them thread local.
+_callback_strs = set()
+_active = Local()
+_active.local_value = _callback_strs
+
+
+def _is_callback(name, urlresolver=None):
+ if urlresolver and not urlresolver._populated:
+ register_callback(urlresolver, _active.local_value)
+ return name in _active.local_value
+
+
+@functools.lru_cache(maxsize=None)
+def lookup_str(urlpattern):
+ """
+ A string that identifies the view (e.g. 'path.to.view_function' or
+ 'path.to.ClassBasedView').
+ """
+ callback = urlpattern.callback
+ if isinstance(callback, functools.partial):
+ callback = callback.func
+ if hasattr(callback, "view_class"):
+ callback = callback.view_class
+ elif not hasattr(callback, "__name__"):
+ return callback.__module__ + "." + callback.__class__.__name__
+ return callback.__module__ + "." + callback.__qualname__
+
+
+def register_callback(urlresolver, thread):
+ for url_pattern in reversed(urlresolver.url_patterns):
+ if isinstance(url_pattern, URLPattern):
+ thread.add(lookup_str(url_pattern))
+ else: # url_pattern is a URLResolver.
+ _active.url_pattern_value = _callback_strs
+ register_callback(url_pattern, _active.url_pattern_value)
+ thread.update(_active.url_pattern_value)
+ urlresolver._populated = True