2009-08-14 3 views
49

Как я могу видеть текущие URL-адреса, на которые смотрит «обратный»?Django: Как я могу увидеть список urlpatterns?

Я вызываю обратное в представлении с аргументом, который, как я думаю, должен работать, но нет. В любом случае, я могу проверить, что там, а почему нет моего шаблона?

+0

HTTP: // stackoverflow.com/questions/1828187/determine-complete-django-url-configuration – pmav99

ответ

45

Попробуйте это:

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

это возвращает функции просмотра, а не URL-адреса –

75
./manage.py show_urls 

Управление должно включать эту функцию по умолчанию.

редактировать После прочтения комментария я понял, что эта функция обеспечивается Джанго-расширений (http://pypi.python.org/pypi/django-extensions/0.7.1)

+0

Это новая функция? – interstar

+2

На самом деле я был неправ, эта функция не предоставляется django в конце концов. – robert

+0

Все, что я получаю от этого: 'TypeError: неподдерживаемый тип операндов для +: 'NoneType' и 'str'' –

13

Существует рецепт на 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) 
+1

. Последняя строка должна быть 'show_urls (urls.url_patterns)'. –

+0

Я получаю 'ModuleNotFoundError: нет модуля с именем 'urls'', не знаю почему? – Alexey

+0

@Alexey Это то, что, вероятно, связано с django 2. Можете ли вы подтвердить это, чтобы я мог обновить ответ? – pmav99

3
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 

В питона управления. py

import urls 
get_resolved_urls(urls.urlpatterns) 
12

Я использую следующую команду:

(Python3 + Джанго 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) 

Использование:

./manage.py showurls 

Пример вывода:

---------------------------------------------------------------------------------------------------- 
| ^(.+)/$    |      | 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>\[email protected][-_\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][email protected][-\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

Обратите внимание, что в документах рекомендуется использовать 'print'. Вместо этого используйте 'self.stdout.write'. https://docs.djangoproject.com/en/1.10/howto/custom-management-commands/ –

+0

Мне нужно было просмотреть/отсортировать пространства имен, а также просмотреть все части URL-адреса, поэтому расширенная команда в http: // stackoverflow. com/a/42388839/179581 – Andrei

+1

@Andrei, если у вас есть результат вашего ответа, это даст другим пользователям возможность увидеть преимущества вашего метода на мне –

1

я продлил Seti's command, чтобы показать пространство имен, все URL-адреса части, автонастройки ширины колонок, отсортированные по (имен, имя): 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: Новая версия с OrderedDict сейчас живет в Джанго-х пакет: https://github.com/5monkeys/django-bananas/blob/master/bananas/management/commands/show_urls.py

4

Джанго 1,11, Python 2.7.6

cd to_your_django_project

python manage.py shell

Затем вставьте следующий код.

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) 

Пример вывода:

^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/^(.+)/$ 
... 
+0

Это ответ, который сработал для меня, хотя я должен был добавить 'None' в строку' urls = urlresolvers.get_resolver (None) ', и иногда я получал« None »в начале некоторых URL-адресов. – Chris

1

Просто введите URL-адрес вы знаете, не существует и сервер возвращает сообщение об ошибке со списком шаблонов URL.

Например, если вы работаете с сайта на http://localhost:8000/something

Тип в

http://localhost:8000/something/blahNonsense, и сервер возвращает список URL для поиска и отображения его в браузере