Skip to content

Instantly share code, notes, and snippets.

@amatmv
Last active March 17, 2021 15:55
Show Gist options
  • Save amatmv/5660fffd6d133269234698b4992f33d2 to your computer and use it in GitHub Desktop.
Save amatmv/5660fffd6d133269234698b4992f33d2 to your computer and use it in GitHub Desktop.
View django urls
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