Django : How can I see a list of urlpatterns?

后端 未结 16 1745
有刺的猬
有刺的猬 2020-11-29 19:36

How can I see the current urlpatterns that \"reverse\" is looking in?

I\'m calling reverse in a view with an argument that I think should work, but doesn\'t. Any wa

16条回答
  •  难免孤独
    2020-11-29 19:37

    I have extended Seti's command to show namespace, all url parts, auto-adjust column widths, sorted by (namespace,name): https://gist.github.com/andreif/263a3fa6e7c425297ffee09c25f66b20

    import sys
    from django.core.management import BaseCommand
    from django.conf.urls import RegexURLPattern, RegexURLResolver
    from django.core import urlresolvers
    
    
    def collect_urls(urls=None, namespace=None, prefix=None):
        if urls is None:
            urls = urlresolvers.get_resolver()
        _collected = []
        prefix = prefix or []
        for x in urls.url_patterns:
            if isinstance(x, RegexURLResolver):
                _collected += collect_urls(x, namespace=x.namespace or namespace,
                                           prefix=prefix + [x.regex.pattern])
            elif isinstance(x, RegexURLPattern):
                _collected.append({'namespace': namespace or '',
                                   'name': x.name or '',
                                   'pattern': prefix + [x.regex.pattern],
                                   'lookup_str': x.lookup_str,
                                   'default_args': dict(x.default_args)})
            else:
                raise NotImplementedError(repr(x))
        return _collected
    
    
    def show_urls():
        all_urls = collect_urls()
        all_urls.sort(key=lambda x: (x['namespace'], x['name']))
    
        max_lengths = {}
        for u in all_urls:
            for k in ['pattern', 'default_args']:
                u[k] = str(u[k])
            for k, v in list(u.items())[:-1]:
                # Skip app_list due to length (contains all app names)
                if (u['namespace'], u['name'], k) == \
                        ('admin', 'app_list', 'pattern'):
                    continue
                max_lengths[k] = max(len(v), max_lengths.get(k, 0))
    
        for u in all_urls:
            sys.stdout.write(' | '.join(
                ('{:%d}' % max_lengths.get(k, len(v))).format(v)
                for k, v in u.items()) + '\n')
    
    
    class Command(BaseCommand):
        def handle(self, *args, **kwargs):
            show_urls()
    

    Note: column order is kept in Python 3.6 and one would need to use OrderedDict in older versions.

    Update: A new version with OrderedDict now lives in django-

提交回复
热议问题