Without further ado, let’s get right to the code.
from django.urls import get_resolver, URLPattern, URLResolver
def get_all_url(resolver=None, pre='/') :
if resolver is None:
resolver = get_resolver()
for r in resolver.url_patterns:
if isinstance(r, URLPattern):
if '<pk>' in str(r.pattern):
continue
yield pre + str(r.pattern).replace(A '^'.' ').replace('$'.' '), r.name
if isinstance(r, URLResolver):
yield from get_all_url(r, pre + str(r.pattern))
if __name__ == '__main__':
Get the full url of the project
for url, name in get_all_url():
print("url='{}' name='{}'".format(url, name))
Get all urls under an app
# Imagine an app called Dashboard
# pass the prefix with the pre argument
for url, name in get_all_url(get_resolver('dashboard.urls')) :print("url='{}' name='{}'".format(url, name))
Copy the code
The get_resolver function is used. Let’s look at the source code and see how this function is used.
# django/urls/resolvers.py
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)
Copy the code
ROOT_URLCONF, which has a default settings.ROOT_URLCONF, is printed as myproject.urls, which is the global routing file for the project.
The return value is URLResolver class, this class is more complex, read the source code is not very clear how to deal with this class.
# django/urls/resolvers.py
class URLResolver:
# Omitted a bunch of code
@cached_property
def urlconf_module(self) :
if isinstance(self.urlconf_name, str) :return import_module(self.urlconf_name)
else:
return self.urlconf_name
@cached_property
def url_patterns(self) :
# urlconf_module might be a valid set of patterns, so we default to it
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
try:
iter(patterns)
except TypeError as e:
msg = (
"The included URLconf '{name}' does not appear to have any "
"patterns in it. If you see valid patterns in the file then "
"the issue is probably caused by a circular import."
)
raise ImproperlyConfigured(msg.format(name=self.urlconf_name)) from e
return patterns
Copy the code
But there’s one method that stands out to me, because we’re going to fetch urls, and we’re going to have to pay special attention to urL-related functions.
Print this out and see if you can find anything.
print(get_resolver('myproject.urls').url_patterns)
# output
# [
#...
# <URLPattern 'api/v1/api-doc' [name='api-doc']>,
# <URLResolver <URLPattern list> (api-docs:api-docs) # 'api/v1/drf-api-doc'>]
Copy the code
The result is a list of two types of elements, the URLPattern class and the URLResolver class.
# django/urls/resolvers.py
class URLPattern:
def __init__(self, pattern, callback, default_args=None, name=None) :
self.pattern = pattern
self.callback = callback # the view
self.default_args = default_args or {}
self.name = name
Copy the code
The former can get the corresponding URL directly, while the latter can also get the result recursively.
This is where we can declare ourselves done.
Follow the public account AlwaysBeta, a variety of back-end development technology dry goods.
Reference article:
- www.ikaze.cn/article/60