Django: Làm cách nào để xem danh sách các urlpattern?


130

Làm cách nào tôi có thể xem các urlpatterns hiện tại mà "đảo ngược" đang xem xét?

Tôi đang gọi ngược lại trong một quan điểm với một lập luận mà tôi nghĩ là nên làm việc, nhưng không. Bất kỳ cách nào tôi có thể kiểm tra xem có gì ở đó và tại sao mẫu của tôi không có?



Bật chế độ Gỡ lỗi và xem danh sách các URL trong đầu ra gỡ lỗi?
boatcoder

Câu trả lời:


181

Nếu bạn muốn có một danh sách tất cả các url trong dự án của mình, trước tiên bạn cần cài đặt django-extension , thêm nó vào cài đặt của bạn như sau:

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

Và sau đó, chạy lệnh này trong thiết bị đầu cuối của bạn

./manage.py show_urls

Để biết thêm thông tin, bạn có thể kiểm tra tài liệu.


3
Thực sự là tôi đã nhầm, tính năng này không phải do django cung cấp.
robert

Tất cả những gì tôi nhận được từ đó làTypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
Paul Tomblin

6
NB: bạn phải thêm django_extensionsđể bạn INSTALLED_APPScài đặt sau
Owen

80

Thử cái này:

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

Hoặc nếu bạn vẫn đang sử dụng Django 1. *:

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

9
này trả lại chức năng xem, không phải là url
Ronen Ness

3
Để có nó trở lại các url, làm điều này thay vì: set (v [1] cho k, v trong get_resolver (None) .reverse_dict.iteritems ())
kloddant

4
Hoặc đối với python3:set(v[1] for k,v in get_resolver(None).reverse_dict.items())
Riêng tư

6
django.core.urlresolversđã bị xóa trong Django 2.0 , thay thế dòng nhập bằngfrom django.urls import get_resolver
hoefling

2
đây không phải đang làm việc cho tôi nữa, chỉ cung cấp cho trở lại một nhóm nhỏ của các url trong dự án của tôi
J__

33

Django> = 2.0 giải pháp

Tôi đã kiểm tra các câu trả lời khác trong bài đăng này và chúng không hoạt động với Django 2.X, không đầy đủ hoặc quá phức tạp. Do đó, đây là công việc của tôi:

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

Mã này in tất cả các URL, không giống như một số giải pháp khác, nó sẽ in đường dẫn đầy đủ và không chỉ nút cuối cùng. ví dụ:

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
Tôi có thể làm thế nào nếu muốn lấy url và tên của chế độ xem ... Bởi vì tôi muốn lấy tên của chế độ xem và mẫu giống như kết quả của bạn ... Vui lòng làm thế nào?
Nathan Ingram

@NathanIngram Chế độ xem được lưu trữ trong thuộc tính "gọi lại" của đối tượng URLPattern, vì vậy bạn có thể thay đổi yield acc + [str(l.pattern)]dòng thành yield acc + [str(l.pattern)], l.callback. Hãy ghi nhớ rằng nó sẽ trở lại chức năng xem bản thân và không phải là một tên
Cesar Canassa

Tôi nhận được lỗi: --- >>>> Lỗi Loại: chuỗi item 0: dự kiến str dụ, danh sách tìm thấy
Nathan Ingram

@NathanIngram "print (''. Join (p))" sẽ không hoạt động vì bây giờ nó là một danh sách các bộ giá trị thay vì một danh sách các chuỗi, hãy thử "print (''. Join (p [0]))".
Cesar Canassa

22

Django 1.11, Python 2.7.6

cd to_your_django_project

python management.py shell

Sau đó dán mã sau.

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)

Đầu ra mẫu:

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

Đây là câu trả lời phù hợp với tôi, mặc dù tôi phải thêm Nonevào dòng urls = urlresolvers.get_resolver(None)và đôi khi tôi nhận được 'Không có' ở đầu một số URL.
Chris,

17

Có một công thức về 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
Dòng cuối cùng nên được show_urls(urls.url_patterns).
Daniel Quinn

1
Tôi nhận được ModuleNotFoundError: No module named 'urls', không biết tại sao?
Alexey

1
@Alexey Đây là một cái gì đó có thể liên quan đến django 2. Bạn có thể xác nhận điều này để tôi có thể cập nhật câu trả lời được không?
pmav99

Tôi đã đặt mã này trong tệp test.pytrong thư mục gốc của dự án của mình và gặp lỗi này, nếu tôi làm import urlstrong trình thông dịch thì tôi cũng gặp lỗi này.
Alexey

Đây không phải là vấn đề Django 1 vs 2: mà import urlslà nhập nội địa, vì vậy bạn có thể cần phải làm from app_name import urls.
Aaron Klein

16

Tôi đang sử dụng lệnh tiếp theo:

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

Sử dụng:

./manage.py showurls

Đầu ra mẫu:

----------------------------------------------------------------------------------------------------
| ^(.+)/$              |                      | 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
Lưu ý rằng các tài liệu khuyên bạn không nên sử dụng print. Thay vào đó sử dụng self.stdout.write. docs.djangoproject.com/en/1.10/howto/custom-management-commands
Dustin Wyatt

Tôi cần xem / sắp xếp theo không gian tên và cũng có thể xem tất cả các phần url, vì vậy đã mở rộng lệnh này trong stackoverflow.com/a/42388839/179581
Andrei

1
@Andrei, nếu bạn có một thực hiện một đầu ra từ câu trả lời của bạn, nó sẽ cung cấp cho những người dùng khác một khả năng nhìn thấy một lợi ích của phương pháp của bạn vào tôi
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

Trong trình bao python management.py

import urls
get_resolved_urls(urls.urlpatterns)

4

Trong Django 3.0, thật dễ dàng như:

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

Bản in: [<URLPattern '' [name='home']>, <URLPattern '/testing' [name='another_url']>]


3

Tôi đã mở rộng lệnh của Seti để hiển thị không gian tên, tất cả các phần url, tự động điều chỉnh độ rộng cột, được sắp xếp theo (không gian tên, tên): 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()

Lưu ý: thứ tự cột được giữ trong Python 3.6 và một cột sẽ cần sử dụng OrderedDicttrong các phiên bản cũ hơn.

Cập nhật: Phiên bản mới với OrderedDict hiện có trong gói django-🍌s: https://github.com/5monkeys/django-bananas/blob/master/bananas/management/commands/show_urls.py


1
from django.conf.urls import RegexURLPattern, RegexURLResolver không hợp lệ hơn trong django> 2.0 Nhưng tôi đã điều chỉnh ý và văn bản tốt ngay bây giờ, thx
cwhisperer

Tôi đã đối mặt với vấn đề này gần đây và cập nhật ý chính. Người ta sẽ cần sử dụng bản sửa đổi trước đó để chạy trên Django <2.0.
Andrei


2

Giải pháp tối giản cho django 2.0

Ví dụ: nếu bạn đang tìm kiếm một url trên ứng dụng đầu tiên của install_apps, bạn có thể truy cập vào nó như sau:

from django.urls import get_resolver
from pprint import pprint

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

Cũng hoạt động cho Django 1. * nếu bạn nhập get_resolvertừ django.core.urlresolvers. Cảm ơn Marcio!
Fernando Costa Bertoldi

2

Django 1.8, Python 2.7+ Chỉ cần chạy các lệnh này trong Shell của bạn. Python management.py shell và thực thi đoạn mã sau.

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
Bạn có thể vui lòng cung cấp thêm chi tiết về câu trả lời của bạn?
toshiro92

1
Tôi đã chỉnh sửa câu trả lời của mình, bạn phải chạy nó trong trình bao của bạn.
Aditya Saini

0

Bạn có thể tạo nhập động để thu thập tất cả các Mẫu URL từ mỗi ứng dụng trong dự án của mình bằng một phương pháp đơn giản như sau:

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

Gần đây tôi đã sử dụng một cái gì đó như thế này để tạo một thẻ mẫu để hiển thị các liên kết điều hướng đang hoạt động.


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

Đây your_main_applà tên ứng dụng nơi đặt tệp settings.py của bạn

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.