Django : urlpatterns 목록을 어떻게 볼 수 있습니까?


130

"reverse"가 찾고있는 현재 urlpatterns를 어떻게 볼 수 있습니까?

나는 작동해야한다고 생각하지만 그렇지 않다는 주장을 가진 관점에서 reverse를 호출하고 있습니다. 어떤 방법으로 거기에 무엇이 있고 왜 내 패턴이 없는지 확인할 수 있습니까?



디버그 모드를 켜고 디버그 출력에서 ​​URL 목록을 확인 하시겠습니까?
boatcoder

답변:


181

프로젝트의 모든 URL 목록을 원하면 먼저 django-extensions 를 설치 하고 다음과 같이 설정에 추가해야합니다.

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

그런 다음 터미널에서이 명령을 실행하십시오.

./manage.py show_urls

자세한 내용 은 설명서 를 참조하십시오 .


3
사실 제가 틀 렸습니다.이 기능은 결국 django에서 제공하지 않습니다.
로버트

내가 얻는 것은TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
Paul Tomblin

6
NB : 설치 후 추가 django_extensions해야합니다INSTALLED_APPS
Owen

80

이 시도:

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

또는 여전히 Django 1. *를 사용하는 경우 :

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

9
이 뷰 기능이 아닌 URL을 반환
Ronen에 네스

3
URL을 반환하도록하려면 대신 다음을 수행하십시오. set (v [1] for k, v in get_resolver (None) .reverse_dict.iteritems ())
kloddant

4
또는 python3의 경우 :set(v[1] for k,v in get_resolver(None).reverse_dict.items())
Private

6
django.core.urlresolvers장고 2.0에서 제거 로 가져 오기 라인을 대체from django.urls import get_resolver
hoefling

2
이것은 더 이상 나를 위해 작동하지 않습니다. 내 프로젝트에서 URL의 작은 하위 집합 만 반환합니다
J__

33

Django> = 2.0 솔루션

이 게시물의 다른 답변을 테스트했으며 Django 2.X에서 작동하지 않거나 불완전하거나 너무 복잡했습니다. 따라서 여기에 내 의견이 있습니다.

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))

이 코드는 다른 솔루션과 달리 모든 URL을 인쇄하지만 마지막 노드뿐만 아니라 전체 경로를 인쇄합니다. 예 :

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

1
url과 view의 이름을 얻고 싶다면 어떻게해야하나요 ... 왜냐하면 내가 당신의 결과와 같은 view의 이름과 패턴을 얻고 싶기 때문에 ... 어떻게하나요?
Nathan Ingram

@NathanIngram 뷰는 URLPattern 개체의 "콜백"속성에 저장되므로 yield acc + [str(l.pattern)]줄을 yield acc + [str(l.pattern)], l.callback. 이 뷰 함수 자체가 아닌 이름을 반환 할 것을 명심하십시오
세자르 Canassa

나는 오류 : --- >>>> 형식 오류 : 순서 항목 0 : 예상 STR 인스턴스 목록이 발견
나단 잉그램을

@NathanIngram "print (". join (p)) "는 이제 문자열 목록 대신 튜플 목록이므로 작동하지 않습니다."print ( ". join (p [0]))"를 시도하십시오.
Cesar Canassa

22

Django 1.11, Python 2.7.6

cd to_your_django_project

파이썬 manage.py 셸

그런 다음 다음 코드를 붙여 넣으십시오.

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

이것은 None줄 에 추가 해야 했지만 urls = urlresolvers.get_resolver(None)일부 URL의 시작 부분에 때때로 '없음' 이 표시되었지만 저에게 효과적이었습니다.
Chris

17

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).
Daniel Quinn

1
나는 점점 ModuleNotFoundError: No module named 'urls', 이유를 몰라?
Alexey

1
@Alexey 이것은 아마도 django 2와 관련이있을 것입니다. 대답을 업데이트 할 수 있도록 이것을 확인해 주시겠습니까?
pmav99

이 코드 test.py를 내 프로젝트의 루트에 있는 파일 에 배치했으며이 import urls오류가 발생합니다. 또한 인터프리터에서 수행 하면이 오류가 발생합니다.
Alexey

Django 1 대 2 문제가 아닙니다. import urls로컬 가져 오기이므로 from app_name import urls.
Aaron Klein

16

다음 명령을 사용하고 있습니다.

(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)

용법:

./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>\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 | {} |
----------------------------------------------------------------------------------------------------

4
문서에서는 print. 대신 self.stdout.write. docs.djangoproject.com/en/1.10/howto/custom-management-commands
Dustin Wyatt

네임 스페이스를보고 / 정렬하고 모든 URL 부분도 볼 필요가 있었
Andrei

1
@Andrei, 당신이 당신의 대답에서 출력을 만들었다면, 그것은 다른 사용자에게 당신의 방법의 이점을 나에게 볼 수있는 능력을 줄 것입니다
PADYMKO


7
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

파이썬 manage.py 셸에서

import urls
get_resolved_urls(urls.urlpatterns)

4

Django 3.0에서는 다음과 같이 쉽습니다.

from django.urls import get_resolver
print(get_resolver().url_patterns)

인쇄물: [<URLPattern '' [name='home']>, <URLPattern '/testing' [name='another_url']>]


3

Seti의 명령 을 확장 하여 네임 스페이스, 모든 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()

참고 : 열 순서는 Python 3.6 에서 유지 OrderedDict되며 이전 버전에서 사용해야 합니다.

업데이트 : OrderedDict가 포함 된 새 버전이 이제 django-🍌의 패키지에 있습니다 : https://github.com/5monkeys/django-bananas/blob/master/bananas/management/commands/show_urls.py


1
django.conf.urls가 RegexURLPattern를 가져올에서 RegexURLResolver는 장고> 2.0 이상 유효하지 않습니다하지만, 좋은 지금 들으 요점 및 wroks 적응
cwhisperer

최근에 직접이 문제에 직면하여 요지를 업데이트했습니다. Django <2.0에서 실행하려면 이전 버전을 사용해야합니다.
Andrei


2

Django 2.0을위한 미니멀리스트 솔루션

예를 들어 installed_apps의 첫 번째 앱에있는 URL을 찾는 경우 다음과 같이 액세스 할 수 있습니다.

from django.urls import get_resolver
from pprint import pprint

pprint(
    get_resolver().url_patterns[0].url_patterns
)

get_resolver에서 가져 오는 경우 Django 1. *에서도 작동합니다 django.core.urlresolvers. 감사합니다 Marcio!
Fernando Costa Bertoldi

2

Django 1.8, Python 2.7+ 셸에서이 명령을 실행하기 만하면됩니다. Python manage.py 셸을 사용하고 다음 코드를 실행합니다.

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)

1
답변에 대한 자세한 내용을 제공해 주시겠습니까?
toshiro92

1
내 대답을 편집 했으므로 쉘에서 이것을 실행해야합니다.
Aditya Saini

0

다음과 같은 간단한 방법으로 프로젝트의 각 애플리케이션에서 모든 URL 패턴을 수집하는 동적 가져 오기를 만들 수 있습니다.

def get_url_patterns():
    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()

최근에 이와 같은 것을 사용하여 활성 탐색 링크를 표시하는 템플릿 태그를 만들었습니다.


0
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

your_main_appsettings.py 파일이있는 앱 이름은 다음과 같습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.