diff options
author | Alokik Vijay <alokik.roe@gmail.com> | 2022-05-17 09:46:26 +0200 |
---|---|---|
committer | Carlton Gibson <carlton@noumenal.es> | 2022-05-17 10:50:09 +0200 |
commit | 7f3cfaa12b28d15c0ca78bb692bfd6e59d17bff1 (patch) | |
tree | b9da3508b15e3bbbb42332f282ce8e0075f5d7e0 /django/contrib/admindocs/utils.py | |
parent | 2a5d2eefc751be012fdebd75d8177c42bf5a76fc (diff) | |
download | django-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.py | 44 |
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 |