Last active
March 17, 2021 15:55
-
-
Save amatmv/5660fffd6d133269234698b4992f33d2 to your computer and use it in GitHub Desktop.
View django urls
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import re | |
import json | |
from django.urls import URLPattern, URLResolver, reverse | |
from django.utils import translation | |
from django.core.exceptions import ViewDoesNotExist | |
from django.core.management import color | |
from django.contrib.admindocs.views import simplify_regex | |
from kavehome_pt import settings | |
from rest_framework import status | |
from django_extensions.management.commands.show_urls import ( | |
RegexURLPattern, | |
RegexURLResolver, | |
LocaleRegexURLResolver, | |
describe_pattern | |
) | |
def extract_views_from_urlpatterns(urlpatterns, base='', namespace=None): | |
""" | |
Return a list of views from a list of urlpatterns. | |
Each object in the returned list is a three-tuple: (view_func, regex, name) | |
""" | |
views = [] | |
for p in urlpatterns: | |
if isinstance(p, (URLPattern, RegexURLPattern)): | |
try: | |
if not p.name: | |
name = p.name | |
elif namespace: | |
name = '{0}:{1}'.format(namespace, p.name) | |
else: | |
name = p.name | |
pattern = describe_pattern(p) | |
views.append((p.callback, base + pattern, name)) | |
except ViewDoesNotExist: | |
continue | |
elif isinstance(p, (URLResolver, RegexURLResolver)): | |
try: | |
patterns = p.url_patterns | |
except ImportError: | |
continue | |
if namespace and p.namespace: | |
_namespace = '{0}:{1}'.format(namespace, p.namespace) | |
else: | |
_namespace = (p.namespace or namespace) | |
pattern = describe_pattern(p) | |
if isinstance(p, LocaleRegexURLResolver): | |
for language in settings.LANGUAGES: | |
with translation.override(language[0]): | |
views.extend(extract_views_from_urlpatterns(patterns, base + pattern, namespace=_namespace)) | |
else: | |
views.extend(extract_views_from_urlpatterns(patterns, base + pattern, namespace=_namespace)) | |
elif hasattr(p, '_get_callback'): | |
try: | |
views.append((p._get_callback(), base + describe_pattern(p), p.name)) | |
except ViewDoesNotExist: | |
continue | |
elif hasattr(p, 'url_patterns') or hasattr(p, '_get_url_patterns'): | |
try: | |
patterns = p.url_patterns | |
except ImportError: | |
continue | |
views.extend(extract_views_from_urlpatterns(patterns, base + describe_pattern(p), namespace=namespace)) | |
else: | |
raise TypeError("%s does not appear to be a urlpattern object" % p) | |
return views | |
def foo(): | |
format_style = 'dense' | |
urlconf = __import__(getattr(settings, 'ROOT_URLCONF'), {}, {}, ['']) | |
view_functions = extract_views_from_urlpatterns(urlconf.urlpatterns) | |
views = [] | |
FMTR = { | |
'dense': "{url}\t{module}\t{url_name}\t{decorator}", | |
'table': "{url},{module},{url_name},{decorator}", | |
'aligned': "{url},{module},{url_name},{decorator}", | |
'verbose': "{url}\n\tController: {module}\n\tURL Name: {url_name}\n\tDecorators: {decorator}\n", | |
'json': '', | |
'pretty-json': '' | |
} | |
def no_style(): | |
style = color.no_style() | |
for role in ( | |
'INFO', 'WARN', 'BOLD', 'URL', 'MODULE', 'MODULE_NAME', 'URL_NAME'): | |
setattr(style, role, lambda msg: msg) | |
return style | |
style = no_style() | |
fmtr = FMTR[format_style] | |
for (func, regex, url_name) in view_functions: | |
if hasattr(func, '__globals__'): | |
func_globals = func.__globals__ | |
elif hasattr(func, 'func_globals'): | |
func_globals = func.func_globals | |
else: | |
func_globals = {} | |
decorator = [] | |
decorators = [d for d in decorator if d in func_globals] | |
import functools | |
if isinstance(func, functools.partial): | |
func = func.func | |
decorators.insert(0, 'functools.partial') | |
if hasattr(func, '__name__'): | |
func_name = func.__name__ | |
elif hasattr(func, '__class__'): | |
func_name = '%s()' % func.__class__.__name__ | |
else: | |
func_name = re.sub(r' at 0x[0-9a-f]+', '', repr(func)) | |
module = '{0}.{1}'.format(func.__module__, func_name) | |
url_name = url_name or '' | |
url = simplify_regex(regex) | |
decorator = ', '.join(decorators) | |
if format_style == 'json': | |
views.append({"url": url, "module": module, "name": url_name, | |
"decorators": decorator}) | |
else: | |
views.append(fmtr.format( | |
module='{0}.{1}'.format(style.MODULE(func.__module__), | |
style.MODULE_NAME(func_name)), | |
url_name=style.URL_NAME(url_name), | |
url=style.URL(url), | |
decorator=decorator, | |
).strip()) | |
if format_style == 'aligned': | |
views = [row.split(',', 3) for row in views] | |
widths = [len(max(columns, key=len)) for columns in zip(*views)] | |
views = [ | |
' '.join('{0:<{1}}'.format(cdata, width) for width, cdata in | |
zip(widths, row)) | |
for row in views | |
] | |
elif format_style == 'table': | |
# Reformat all data and show in a table format | |
views = [row.split(',', 3) for row in views] | |
widths = [len(max(columns, key=len)) for columns in zip(*views)] | |
table_views = [] | |
header = (style.MODULE_NAME('URL'), style.MODULE_NAME('Module'), | |
style.MODULE_NAME('Name'), style.MODULE_NAME('Decorator')) | |
table_views.append( | |
' | '.join('{0:<{1}}'.format(title, width) for width, title in | |
zip(widths, header)) | |
) | |
table_views.append('-+-'.join('-' * width for width in widths)) | |
for row in views: | |
table_views.append( | |
' | '.join('{0:<{1}}'.format(cdata, width) for width, cdata in | |
zip(widths, row)) | |
) | |
# Replace original views so we can return the same object | |
views = table_views | |
elif format_style == 'json': | |
return json.dumps(views, indent=4) | |
return "\n".join([v for v in views]) + "\n" | |
print(foo()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment