250

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 way I can check what's there and why my pattern isn't?

2
  • stackoverflow.com/questions/1828187/… Commented May 26, 2014 at 16:04
  • 2
    Turn on DEBUG mode and look at the list of URLS in the debug output? Commented Jun 13, 2019 at 15:08

22 Answers 22

321

If you want a list of all the urls in your project, first you need to install django-extensions

You can simply install using command.

pip install django-extensions 

For more information related to package goto django-extensions

After that, add django_extensions in INSTALLED_APPS in your settings.py file like this:

INSTALLED_APPS = ( ... 'django_extensions', ... ) 

urls.py example:

from django.urls import path, include from . import views from . import health_views urlpatterns = [ path('get_url_info', views.get_url_func), path('health', health_views.service_health_check), path('service-session/status', views.service_session_status) ] 

And then, run any of the command in your terminal

python manage.py show_urls 

or

./manage.py show_urls 

Sample output example based on config urls.py:

/get_url_info django_app.views.get_url_func /health django_app.health_views.service_health_check /service-session/status django_app.views.service_session_status 

For more information you can check the documentation.

Sign up to request clarification or add additional context in comments.

3 Comments

Actually I was wrong, this feature is not provided by django after all.
All I get from that is TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
NB: you have to add django_extensions to your INSTALLED_APPS after installing
124

Try this:

from django.urls import get_resolver get_resolver().reverse_dict.keys() 

Or if you're still on Django 1.*:

from django.core.urlresolvers import get_resolver get_resolver(None).reverse_dict.keys() 

5 Comments

this return the view functions, not the urls
To have it return the urls, do this instead: set(v[1] for k,v in get_resolver(None).reverse_dict.iteritems())
Or for python3: set(v[1] for k,v in get_resolver(None).reverse_dict.items())
django.core.urlresolvers was removed in Django 2.0, replace the import line with from django.urls import get_resolver
this isn't working for me anymore, only gives back a small subset of the urls in my project
94

Django >= 2.0 solution

I tested the other answers in this post and they were either not working with Django 2.X, incomplete or too complex. Therefore, here is my take on this:

from django.conf import settings from django.urls import URLPattern, URLResolver urlconf = __import__(settings.ROOT_URLCONF, {}, {}, ['']) def list_urls(lis, acc=None): if acc is None: acc = [] if not lis: return l = lis[0] if isinstance(l, URLPattern): yield acc + [str(l.pattern)] elif isinstance(l, URLResolver): yield from list_urls(l.url_patterns, acc + [str(l.pattern)]) yield from list_urls(lis[1:], acc) for p in list_urls(urlconf.urlpatterns): print(''.join(p)) 

This code prints all URLs, unlike some other solutions it will print the full path and not only the last node. e.g.:

admin/ admin/login/ admin/logout/ admin/password_change/ admin/password_change/done/ admin/jsi18n/ admin/r/<int:content_type_id>/<path:object_id>/ admin/auth/group/ admin/auth/group/add/ admin/auth/group/autocomplete/ admin/auth/group/<path:object_id>/history/ admin/auth/group/<path:object_id>/delete/ admin/auth/group/<path:object_id>/change/ admin/auth/group/<path:object_id>/ admin/auth/user/<id>/password/ admin/auth/user/ ... etc, etc 

5 Comments

How can i do if want to get url and name of view ... Because me i want to get name of view and pattern like your result ... Please how ?
@NathanIngram The view is stored in the "callback" property of the URLPattern object, so you could change the yield acc + [str(l.pattern)] line to yield acc + [str(l.pattern)], l.callback. Keep in mind that it will return the view function itself and not a name
I get error: --->>>> TypeError: sequence item 0: expected str instance, list found
@NathanIngram The "print(''.join(p))" won't work because it's now a list of tuples instead of a list of strings, try "print(''.join(p[0]))".
Awesome example of tail recurency :) BTW - if someone wants to get view class just change yield acc + [str(l.pattern)] to yield [l.callback.view_class]
32

Here is a quick and dirty hack to just get the information you need without needing to modify any of your settings.

pip install django-extensions python manage.py shell -c 'from django.core.management import call_command; from django_extensions.management.commands.show_urls import Command; call_command(Command())' 

This is piggy backing off @robert's answer. While correct, I didn't want to have django-extensions as a dependency even if it was for just a second.

4 Comments

What's wrong with django-extensions as a dependency?
@AlxVallejo Absolutely nothing! It’s a great well-maintained-module, but if you’re using it every 5 months because you just need to list out your urls (my scenario).. my solution might just be your thing. If you rely on it on a day-to-day, by all means: install it!
I get 'python3: can't open file 'manage.py': [Errno 2] No such file or directory'
@J.Bailleul you need to be in the root of your project; where the main "manage.py" file is, the "entrypoint" into django.
29

Django 1.11, Python 2.7.6

cd to_your_django_project

python manage.py shell

Then paste following code.

from django.conf.urls import RegexURLPattern, RegexURLResolver from django.core import urlresolvers urls = urlresolvers.get_resolver() def if_none(value): if value: return value return '' def print_urls(urls, parent_pattern=None): for url in urls.url_patterns: if isinstance(url, RegexURLResolver): print_urls(url, if_none(parent_pattern) + url.regex.pattern) elif isinstance(url, RegexURLPattern): print(if_none(parent_pattern) + url.regex.pattern) print_urls(urls) 

Sample output:

^django-admin/^$ ^django-admin/^login/$ ^django-admin/^logout/$ ^django-admin/^password_change/$ ^django-admin/^password_change/done/$ ^django-admin/^jsi18n/$ ^django-admin/^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$ ^django-admin/^wagtailimages/image/^$ ^django-admin/^wagtailimages/image/^add/$ ^django-admin/^wagtailimages/image/^(.+)/history/$ ^django-admin/^wagtailimages/image/^(.+)/delete/$ ^django-admin/^wagtailimages/image/^(.+)/change/$ ^django-admin/^wagtailimages/image/^(.+)/$ ... 

1 Comment

This is the answer that worked for me, although I had to add None to the line urls = urlresolvers.get_resolver(None), and I did sometimes get 'None' at the start of some URLs.
27

In Django 3.0, it's as easy as:

>>> from django.urls import get_resolver >>> print(get_resolver().url_patterns) [<URLPattern '' [name='home']>, <URLPattern '/testing' [name='another_url']>] 

To get the patterns for a particular app, you could use the following:

from django.urls import get_resolver, URLPattern def get_patterns(app: str) -> List[URLPattern]: for pattern in get_resolver().url_patterns: if getattr(pattern, "app_name", "") == app: return pattern.urlconf_name 
>>> get_patterns("admin") [<URLPattern '' [name='index']>, <URLPattern 'login/' [name='login']>, <URLPattern 'logout/' [name='logout']>, <URLPattern 'password_change/' [name='password_change']>, <URLPattern 'password_change/done/' [name='password_change_done']>, <URLPattern 'autocomplete/' [name='autocomplete']>, <URLPattern 'jsi18n/' [name='jsi18n']> 

1 Comment

Doesn't work in my case, only prints one API URL: [<URLResolver <URLPattern list> (None:None) 'api/v1/'>, <URLPattern '^$'>, <URLPattern '^media/(?P<path>.*)$'>]
17

I am using the next command:

(Python3 + Django 1.10)

from django.core.management import BaseCommand from django.conf.urls import RegexURLPattern, RegexURLResolver from django.core import urlresolvers class Command(BaseCommand): def add_arguments(self, parser): pass def handle(self, *args, **kwargs): urls = urlresolvers.get_resolver() all_urls = list() def func_for_sorting(i): if i.name is None: i.name = '' return i.name def show_urls(urls): for url in urls.url_patterns: if isinstance(url, RegexURLResolver): show_urls(url) elif isinstance(url, RegexURLPattern): all_urls.append(url) show_urls(urls) all_urls.sort(key=func_for_sorting, reverse=False) print('-' * 100) for url in all_urls: print('| {0.regex.pattern:20} | {0.name:20} | {0.lookup_str:20} | {0.default_args} |'.format(url)) print('-' * 100) 

Usage:

./manage.py showurls 

Sample output:

---------------------------------------------------------------------------------------------------- | ^(.+)/$ | | django.views.generic.base.RedirectView | {} | | ^(.+)/$ | | django.views.generic.base.RedirectView | {} | | ^(.+)/$ | | django.views.generic.base.RedirectView | {} | | ^(.+)/$ | | django.views.generic.base.RedirectView | {} | | ^(.+)/$ | | django.views.generic.base.RedirectView | {} | | ^(.+)/$ | | django.views.generic.base.RedirectView | {} | | ^static\/(?P<path>.*)$ | | django.contrib.staticfiles.views.serve | {} | | ^media\/(?P<path>.*)$ | | django.views.static.serve | {'document_root': '/home/wlysenko/.virtualenvs/programmerHelper/project/media'} | | ^(?P<app_label>polls|snippets|questions)/$ | app_list | apps.core.admin.AdminSite.app_index | {} | | ^(?P<app_label>activity|articles|badges|books|comments|flavours|forum|marks|newsletters|notifications|opinions|polls|questions|replies|snippets|solutions|tags|testing|users|utilities|visits)/reports/$ | app_reports | apps.core.admin.AdminSite.reports_view | {} | | ^(?P<app_label>activity|articles|badges|books|comments|flavours|forum|marks|newsletters|notifications|opinions|polls|questions|replies|snippets|solutions|tags|testing|users|utilities|visits)/statistics/$ | app_statistics | apps.core.admin.AdminSite.statistics_view | {} | | articles/(?P<slug>[-\w]+)/$ | article | apps.articles.views.ArticleDetailView | {} | | book/(?P<slug>[-_\w]+)/$ | book | apps.books.views.BookDetailView | {} | | category/(?P<slug>[-_\w]+)/$ | category | apps.utilities.views.CategoryDetailView | {} | | create/$ | create | apps.users.views.UserDetailView | {} | | delete/$ | delete | apps.users.views.UserDetailView | {} | | detail/(?P<email>\w+@[-_\w]+.\w+)/$ | detail | apps.users.views.UserDetailView | {} | | snippet/(?P<slug>[-_\w]+)/$ | detail | apps.snippets.views.SnippetDetailView | {} | | (?P<contenttype_model_pk>\d+)/(?P<pks_separated_commas>[-,\w]*)/$ | export | apps.export_import_models.views.ExportTemplateView | {} | | download_preview/$ | export_preview_download | apps.export_import_models.views.ExportPreviewDownloadView | {} | | ^$ | import | apps.export_import_models.views.ImportTemplateView | {} | | result/$ | import_result | apps.export_import_models.views.ImportResultTemplateView | {} | | ^$ | index | django.contrib.admin.sites.AdminSite.index | {} | | ^$ | index | apps.core.views.IndexView | {} | | ^jsi18n/$ | javascript-catalog | django.views.i18n.javascript_catalog | {'packages': ('your.app.package',)} | | ^jsi18n/$ | jsi18n | django.contrib.admin.sites.AdminSite.i18n_javascript | {} | | level/(?P<slug>[-_\w]+)/$ | level | apps.users.views.UserDetailView | {} | | ^login/$ | login | django.contrib.admin.sites.AdminSite.login | {} | | ^logout/$ | logout | django.contrib.admin.sites.AdminSite.logout | {} | | newsletter/(?P<slug>[_\w]+)/$ | newsletter | apps.newsletters.views.NewsletterDetailView | {} | | newsletters/$ | newsletters | apps.newsletters.views.NewslettersListView | {} | | notification/(?P<account_email>[-\w]+@[-\w]+.\w+)/$ | notification | apps.notifications.views.NotificationDetailView | {} | | ^password_change/$ | password_change | django.contrib.admin.sites.AdminSite.password_change | {} | | ^password_change/done/$ | password_change_done | django.contrib.admin.sites.AdminSite.password_change_done | {} | | ^image/(?P<height>\d+)x(?P<width>\d+)/$ | placeholder | apps.core.views.PlaceholderView | {} | | poll/(?P<pk>\w{8}-\w{4}-\w{4}-\w{4}-\w{12})/(?P<slug>[-\w]+)/$ | poll | apps.polls.views.PollDetailView | {} | | ^add/$ | polls_choice_add | django.contrib.admin.options.ModelAdmin.add_view | {} | | ^(.+)/change/$ | polls_choice_change | django.contrib.admin.options.ModelAdmin.change_view | {} | | ^$ | polls_choice_changelist | django.contrib.admin.options.ModelAdmin.changelist_view | {} | | ^(.+)/delete/$ | polls_choice_delete | django.contrib.admin.options.ModelAdmin.delete_view | {} | | ^(.+)/history/$ | polls_choice_history | django.contrib.admin.options.ModelAdmin.history_view | {} | | ^add/$ | polls_poll_add | django.contrib.admin.options.ModelAdmin.add_view | {} | | ^(.+)/change/$ | polls_poll_change | django.contrib.admin.options.ModelAdmin.change_view | {} | | ^$ | polls_poll_changelist | django.contrib.admin.options.ModelAdmin.changelist_view | {} | | ^(.+)/delete/$ | polls_poll_delete | django.contrib.admin.options.ModelAdmin.delete_view | {} | | ^(.+)/history/$ | polls_poll_history | django.contrib.admin.options.ModelAdmin.history_view | {} | | ^$ | polls_vote_changelist | django.contrib.admin.options.ModelAdmin.changelist_view | {} | | publisher/(?P<slug>[-_\w]+)/$ | publisher | apps.books.views.PublisherDetailView | {} | | question/(?P<slug>[-_\w]+)/$ | question | apps.questions.views.QuestionDetailView | {} | | ^add/$ | questions_answer_add | django.contrib.admin.options.ModelAdmin.add_view | {} | | ^(.+)/change/$ | questions_answer_change | django.contrib.admin.options.ModelAdmin.change_view | {} | | ^$ | questions_answer_changelist | django.contrib.admin.options.ModelAdmin.changelist_view | {} | | ^(.+)/delete/$ | questions_answer_delete | django.contrib.admin.options.ModelAdmin.delete_view | {} | | ^(.+)/history/$ | questions_answer_history | django.contrib.admin.options.ModelAdmin.history_view | {} | | ^add/$ | questions_question_add | django.contrib.admin.options.ModelAdmin.add_view | {} | | ^(.+)/change/$ | questions_question_change | django.contrib.admin.options.ModelAdmin.change_view | {} | | ^$ | questions_question_changelist | django.contrib.admin.options.ModelAdmin.changelist_view | {} | | ^(.+)/delete/$ | questions_question_delete | django.contrib.admin.options.ModelAdmin.delete_view | {} | | ^(.+)/history/$ | questions_question_history | django.contrib.admin.options.ModelAdmin.history_view | {} | | ^setlang/$ | set_language | django.views.i18n.set_language | {} | | ^add/$ | snippets_snippet_add | django.contrib.admin.options.ModelAdmin.add_view | {} | | ^(.+)/change/$ | snippets_snippet_change | django.contrib.admin.options.ModelAdmin.change_view | {} | | ^$ | snippets_snippet_changelist | django.contrib.admin.options.ModelAdmin.changelist_view | {} | | ^(.+)/delete/$ | snippets_snippet_delete | django.contrib.admin.options.ModelAdmin.delete_view | {} | | ^(.+)/history/$ | snippets_snippet_history | django.contrib.admin.options.ModelAdmin.history_view | {} | | solution/(?P<pk>\w{8}-\w{4}-\w{4}-\w{4}-\w{12})/(?P<slug>[-_\w]+)/$ | solution | apps.solutions.views.SolutionDetailView | {} | | suit/(?P<slug>[-\w]+)/$ | suit | apps.testing.views.SuitDetailView | {} | | tag/(?P<name>[-_\w]+)/$ | tag | apps.tags.views.TagDetailView | {} | | theme/(?P<slug>[-_\w]+)/$ | theme | apps.forum.views.SectionDetailView | {} | | topic/(?P<slug>[-_\w]+)/$ | topic | apps.forum.views.TopicDetailView | {} | | update/$ | update | apps.users.views.UserDetailView | {} | | ^r/(?P<content_type_id>\d+)/(?P<object_id>.+)/$ | view_on_site | django.contrib.contenttypes.views.shortcut | {} | | writer/(?P<slug>[-_\w]+)/$ | writer | apps.books.views.WriterDetailView | {} | ---------------------------------------------------------------------------------------------------- 

3 Comments

Note that the docs recommend you don't use print. Instead use self.stdout.write. docs.djangoproject.com/en/1.10/howto/custom-management-commands
I needed to see/sort-by namespaces and also see all url parts, so extended this command in stackoverflow.com/a/42388839/179581
@Andrei, if you have a made an output from your answer, it would give other users an ability to see a benefit of your method on me
15

There is a recipe on activestate

import urls def show_urls(urllist, depth=0): for entry in urllist: print(" " * depth, entry.regex.pattern) if hasattr(entry, 'url_patterns'): show_urls(entry.url_patterns, depth + 1) show_urls(urls.url_patterns) 

5 Comments

That last line should be show_urls(urls.url_patterns).
I'm getting ModuleNotFoundError: No module named 'urls', dont know why?
@Alexey This is something that probably has to do with django 2. Can you confirm this please so that I can update the answer?
I've placed this code in file test.py in the root of my project and has this error, also if i do import urls in interpreter then i also get this error.
It's not a Django 1 vs 2 issue: the import urls is a local import, so you probably need to do from app_name import urls.
10

There's a plugin I use: https://github.com/django-extensions/django-extensions, it has a show_urls command that could help.

Comments

8

Simply type in a url you know does not exist and the server will return an error message with a list of url patterns.

For example, if you're running a site at http://localhost:8000/something

Type in

http://localhost:8000/something/blahNonsense, and your server will return the url search list and display it in the browser

1 Comment

This is what I use, but I've encountered one limitation: it doesn't (not always?) expand included URL modules.
6
def get_resolved_urls(url_patterns): url_patterns_resolved = [] for entry in url_patterns: if hasattr(entry, 'url_patterns'): url_patterns_resolved += get_resolved_urls( entry.url_patterns) else: url_patterns_resolved.append(entry) return url_patterns_resolved 

In python manage.py shell

import urls get_resolved_urls(urls.urlpatterns) 

Comments

6

Minimalist solution for django 2.0

For instance, if you're looking for an url that's on the first app of installed_apps, you can access it like that:

from django.urls import get_resolver from pprint import pprint pprint( get_resolver().url_patterns[0].url_patterns ) 

1 Comment

Works for Django 1.* too if you import get_resolver from django.core.urlresolvers. Thanks Marcio!
4

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-🍌s package: https://github.com/5monkeys/django-bananas/blob/master/bananas/management/commands/show_urls.py

2 Comments

from django.conf.urls import RegexURLPattern, RegexURLResolver is not more valid in django > 2.0 But I adapted the gist and wroks fine now, thx
Faced this issue myself recently and updated the gist. One would need to use an earlier revision to run on Django < 2.0.
4

Django 1.8, Python 2.7+ Just run these commands in your Shell. Python manage.py shell and execute the following code.

from django.conf.urls import RegexURLPattern, RegexURLResolver from django.core import urlresolvers urls = urlresolvers.get_resolver(None) def if_none(value): if value: return value return '' def print_urls(urls, parent_pattern=None): for url in urls.url_patterns: if isinstance(url, RegexURLResolver): print_urls(url, if_none(parent_pattern) + url.regex.pattern) elif isinstance(url, RegexURLPattern): print(if_none(parent_pattern) + url.regex.pattern) print_urls(urls) 

Comments

1
from django.urls.resolvers import RegexPattern,RoutePattern from your_main_app import urls def get_urls(): url_list = [] for url in urls.urlpatterns: url_list.append(url.pattern._regex) if isinstance(url.pattern, RegexPattern) else url_list.append(url.pattern._route) return url_list 

Here your_main_app is the app name where your settings.py file is placed

Comments

1

Django >= 2.0 List Solution

adopted from @CesarCanassa

from django.conf import settings from django.urls import URLPattern, URLResolver URLCONF = __import__(settings.ROOT_URLCONF, {}, {}, ['']) def list_urls(patterns, path=None): """ recursive """ if not path: path = [] result = [] for pattern in patterns: if isinstance(pattern, URLPattern): result.append(''.join(path) + str(pattern.pattern)) elif isinstance(pattern, URLResolver): result += list_urls(pattern.url_patterns, path + [str(pattern.pattern)]) return result 

1 Comment

To get URLPattern name variable (this will give you reverse name eg name:name from path): replace result.append(''.join(path) + str(pattern.pattern)) with result.append(str(pattern.name))
1

Yet another adaption of @Cesar Canassa 's generator magic. This can be added to the yourapp/management/commands/dumpurls.py director of your app so that it'll be accessible as a subcommand in management.py.

note: I added a line to make sure it filters for only yourapp. Update or remove it accordingly if additional URLs are desired.

As a management.py Subcommand

Deploy Path: yourapp/management/commands/dumpurls.py

from django.core.management.base import BaseCommand, CommandError from django.conf import settings from django.urls import URLPattern, URLResolver def list_urls(lis, acc=None): if acc is None: acc = [] if not lis: return l = lis[0] if isinstance(l, URLPattern): yield acc + [str(l.pattern),l.name] elif isinstance(l, URLResolver): yield from list_urls(l.url_patterns, acc + [str(l.pattern)]) yield from list_urls(lis[1:], acc) class Command(BaseCommand): help = 'List all URLs from the urlconf' def handle(self, *args, **options): urlconf = __import__(settings.ROOT_URLCONF, {}, {}, ['']) records, glen, nlen = [], 0, 0 for p in list_urls(urlconf.urlpatterns): record = [''.join(p[:2]), p[2]] # Update me, or add an argument if record[0].startswith('yourapp'): clen = len(record[0]) if clen > glen: glen = clen clen = len(record[1]) if clen > nlen: nlen = clen records.append(record) self.stdout.write('{:-<{width}}'.format('',width=glen+nlen)) self.stdout.write('{:<{glen}}Name'.format('Path',glen=glen+4)) self.stdout.write('{:-<{width}}'.format('',width=glen+nlen)) for record in records: self.stdout.write('{path:<{glen}}{name}'.format(path=record[0], name=record[1], glen=glen+4)) self.stdout.write('{:-<{width}}'.format('',width=glen+nlen)) 

Sample Output

(env) django@dev:myproj~> ./manage.py dumpurls ------------------------------------------------------------------------------------------------------- Path Name ------------------------------------------------------------------------------------------------------- yourapp/^api-key/$ api-key-list yourapp/^api-key\.(?P<format>[a-z0-9]+)/?$ api-key-list yourapp/^attacks/$ attack-list yourapp/^attacks\.(?P<format>[a-z0-9]+)/?$ attack-list yourapp/^attack-histories/$ attackhistory-list yourapp/^attack-histories\.(?P<format>[a-z0-9]+)/?$ attackhistory-list yourapp/^files/$ file-list yourapp/^files\.(?P<format>[a-z0-9]+)/?$ file-list yourapp/^modules/$ module-list yourapp/^modules\.(?P<format>[a-z0-9]+)/?$ module-list 

Comments

1

You can create a dynamic import to gather all URL Patterns from each application in your project with a simple method like so:

def get_url_patterns(): import importlib from django.apps import apps list_of_all_url_patterns = list() for name, app in apps.app_configs.items(): # you have a directory structure where you should be able to build the correct path # my example shows that apps.[app_name].urls is where to look mod_to_import = f'apps.{name}.urls' try: urls = getattr(importlib.import_module(mod_to_import), "urlpatterns") list_of_all_url_patterns.extend(urls) except ImportError as ex: # is an app without urls pass return list_of_all_url_patterns 

list_of_all_url_patterns = get_url_patterns()

I recently used something like this to create a template tag to show active navigation links.

Comments

1
import subprocces res = subprocess.run( 'python manage.py show_urls', capture_output=True, shell=True, ) url_list = [ line.split('\t')[0] for line in res.stdout.decode().split('\n') ] 

2 Comments

Can u explain it a little?
@FaisalNazik subprocess.run() allows you to run command line executables from python. You can pass the show_urls argument to manage.py, capture the output, which has to use the shell option (by default - as far as I know) and save it to the res variable. url_list is then a list... it uses a "generator" structure to generate each list item. Assuming that res outputs coded URLs with a \t character at the end of each one, we take a list item and split it then take the remainder (the first element), ie [item for line in ...]. ... is needed to iterate over all URLs and read them.
1

In case you are using DRF, you can print all the URL patterns for a particular router by printing the urlpatterns from router.get_urls() (within your Django app's urls.py file).

Open your apps urls.py and add the print statement to the bottom of the file, so the whole file might look like this:

import pprint from django.urls import include, path from rest_framework import routers from . import views router = routers.DefaultRouter() router.register(r"users", views.UserViewSet, basename="User") router.register(r"auth", views.AuthenticationView, basename="Auth") router.register(r"dummy", views.DummyViewSet, basename="Dummy") router.register("surveys", views.SurveyViewSet, basename="survey") urlpatterns = [ path("", include(router.urls)), ] pprint.pprint(router.get_urls()) 

The patterns are then printed like this:

[<URLPattern '^users/$' [name='User-list']>, <URLPattern '^users\.(?P<format>[a-z0-9]+)/?$' [name='User-list']>, <URLPattern '^users/admins/$' [name='User-admins']>, <URLPattern '^users/admins\.(?P<format>[a-z0-9]+)/?$' [name='User-admins']>, <URLPattern '^users/current/$' [name='User-current']>, <URLPattern '^users/current\.(?P<format>[a-z0-9]+)/?$' [name='User-current']>, <URLPattern '^users/(?P<pk>[^/.]+)/$' [name='User-detail']>, <URLPattern '^users/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='User-detail']>, <URLPattern '^auth/login/$' [name='Auth-login']>, ... ] 

Comments

1

In my case I want to list api endpoints without having to basically rewrite my urlpatterns. You can't import urlpatterns into the view since it causes a circular import. So here is a pretty good solution using the include function from django.urls. This allows you to list any set of urlpatterns in the project.

from django.views.generic import TemplateView from rest_framework.response import Response from rest_framework.routers import APIRootView from rest_framework.schemas import get_schema_view from django.urls import include import re # Create your views here. class ApiRoot(APIRootView): def get(self, request, *args, **kwargs): urls = include('api.urls')[0].urlpatterns response = {} for url in urls: match = re.search(r'[\w\/\-]+', str(url.pattern)) if not match: continue name = match.group() response[name] = request.build_absolute_uri(name) return Response(response) 

enter image description here Copy and paste this and fix up some stuff. Hacky solution that works great for me.

Comments

-1

If you just want to browse them all, just go to, e.g.:

http://127.0.0.1:8000/admin/doc/views/ 

1 Comment

Note this needs the admin docs contrib installed.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.