Django: URL şablonlarının bir listesini nasıl görebilirim?


130

"Tersine" bakılan mevcut url şablonlarını nasıl görebilirim?

İşe yaraması gerektiğini düşündüğüm ama işe yaramadığını düşündüğüm bir argümanla birlikte tersine çağırıyorum. Orada ne olduğunu ve modelimin neden olmadığını kontrol etmemin bir yolu var mı?



HATA AYIKLAMA modunu açın ve hata ayıklama çıktısındaki URL'lerin listesine bakın.
boatcoder

Yanıtlar:


181

Projenizdeki tüm url'lerin bir listesini istiyorsanız, önce django uzantılarını kurmanız gerekir , bunu şu şekilde ayarlarınıza ekleyin:

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

Ve sonra, terminalinizde bu komutu çalıştırın

./manage.py show_urls

Daha fazla bilgi için belgelere bakabilirsiniz .


3
Aslında yanılmışım, sonuçta bu özellik django tarafından sağlanmıyor.
robert

Bundan tek aldığımTypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
Paul Tomblin

6
Not: django_extensionsINSTALLED_APPS
Owen

80

Bunu dene:

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

Veya hala Django 1'de iseniz *:

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

9
bu, url'leri değil, görünüm işlevlerini döndürür
Ronen Ness

3
URL'leri döndürmesini sağlamak için, şunu yapın: set (v [1] for k, v in get_resolver (None) .reverse_dict.iteritems ())
kloddant

4
Veya python3 için:set(v[1] for k,v in get_resolver(None).reverse_dict.items())
Özel

6
django.core.urlresolversDjango 2.0'da kaldırıldı , ithalat satırınıfrom django.urls import get_resolver
hoefling

2
bu artık benim için çalışmıyor,
projemdeki

33

Django> = 2.0 çözümü

Bu gönderideki diğer cevapları test ettim ve ya Django 2.X ile çalışmıyorlardı, eksik ya da çok karmaşık. Bu nedenle, işte bu konudaki görüşüm:

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

Bu kod, diğer bazı çözümlerden farklı olarak tüm URL'leri yazdırır, yalnızca son düğümü değil, tam yolu yazdırır. Örneğin:

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 ve view ismini almak istersem nasıl yapabilirim ... Çünkü benden sonucunuz gibi görünüm adı ve desen almak istiyorum ... Lütfen nasıl?
Nathan Ingram

@NathanIngram Görünüm, URLPattern nesnesinin "geri arama" özelliğinde saklanır, böylece yield acc + [str(l.pattern)]satırı olarak değiştirebilirsiniz yield acc + [str(l.pattern)], l.callback. Görünüm işlevinin bir ad değil, kendisini döndüreceğini unutmayın
Cesar Canassa

Hata alıyorum: --- >>>> TypeError: sıra öğesi 0: beklenen str örneği, liste bulundu
Nathan Ingram

@NathanIngram "print (''. Join (p))" çalışmaz çünkü artık bir dizge listesi yerine tuple listesidir, "print (". Join (p [0])) "deneyin.
Cesar Canassa

22

Django 1.11, Python 2.7.6

cd to_your_django_project

python manage.py kabuğu

Ardından aşağıdaki kodu yapıştırın.

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)

Örnek çıktı:

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

Bu benim için işe yarayan cevaptı, ancak Nonesatıra eklemem gerekiyordu urls = urlresolvers.get_resolver(None)ve bazen bazı URL'lerin başında 'Hiçbiri' aldım.
Chris

17

Activestate hakkında bir tarif var

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
Bu son satır olmalıdır show_urls(urls.url_patterns).
Daniel Quinn

1
Ben alıyorum ModuleNotFoundError: No module named 'urls', nedenini bilmiyorum?
Alexey

1
@Alexey Bu muhtemelen django 2 ile ilgisi olan bir şeydir. Cevabı güncelleyebilmem için lütfen bunu onaylayabilir misiniz?
pmav99

Bu kodu test.pyprojemin kök dizinindeki dosyaya yerleştirdim ve bu hatayı alıyorum, ayrıca import urlsyorumlayıcıda yaparsam bu hatayı da alıyorum.
Alexey

Bu bir Django 1 vs 2 sorunu değil: import urlsyerel bir içe aktarmadır, bu yüzden muhtemelen yapmanız gerekir from app_name import urls.
Aaron Klein

16

Bir sonraki komutu kullanıyorum:

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

Kullanımı:

./manage.py showurls

Örnek çıktı:

----------------------------------------------------------------------------------------------------
| ^(.+)/$              |                      | 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
Dokümanların kullanmamanızı önerdiğini unutmayın print. Bunun yerine kullanın self.stdout.write. docs.djangoproject.com/en/1.10/howto/custom-management-commands
Dustin Wyatt

Ad alanlarını görmem / sıralamam ve ayrıca tüm url parçalarını görmem gerekiyordu, bu nedenle bu komutu stackoverflow.com/a/42388839/179581
Andrei

1
@Andrei, cevabınızdan bir çıktı aldıysanız, bu diğer kullanıcılara yönteminizin bir faydasını benim üzerimde görme imkanı verir
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

Python manage.py shell'de

import urls
get_resolved_urls(urls.urlpatterns)

4

Django 3.0'da şu kadar kolaydır:

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

Baskılar: [<URLPattern '' [name='home']>, <URLPattern '/testing' [name='another_url']>]


3

Seti'nin komutunu ad alanını, tüm url parçalarını, sütun genişliklerini otomatik olarak ayarlayarak (ad alanı, ad) sıralaması için genişlettim : 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()

Not: sütun sırası Python 3.6'da tutulur ve OrderedDicteski sürümlerde birinin kullanılması gerekir .

Güncelleme: OrderedDict'in yeni bir sürümü artık django'nun paketinde bulunuyor: https://github.com/5monkeys/django-bananas/blob/master/bananas/management/commands/show_urls.py


1
django.conf.urls'den RegexURLPattern içe aktar, RegexURLResolver, django> 2.0'da daha geçerli değil Ama özü uyarladım ve şimdi güzelce kırıldım, thx
cwhisperer

Bu sorunla yakın zamanda kendim karşı karşıya kaldım ve özü güncelledim. Django <2.0 üzerinde çalışmak için daha önceki bir revizyonun kullanılması gerekir.
Andrei


2

Django 2.0 için minimalist çözüm

Örneğin, install_apps uygulamasının ilk uygulamasında olan bir url arıyorsanız, ona şu şekilde erişebilirsiniz:

from django.urls import get_resolver
from pprint import pprint

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

İçe çok eğer Django 1. İşleri * get_resolverdan django.core.urlresolvers. Teşekkürler Marcio!
Fernando Costa Bertoldi

2

Django 1.8, Python 2.7+ Sadece bu komutları Kabuğunuzda çalıştırın. Python manage.py kabuğunu çalıştırın ve aşağıdaki kodu çalıştırın.

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
Cevabınız hakkında daha fazla ayrıntı verebilir misiniz?
toshiro92

1
Cevabımı düzenledim, bunu kabuğunuzda çalıştırmalısınız.
Aditya Saini

0

Projenizdeki her uygulamadan tüm URL Modellerini aşağıdaki gibi basit bir yöntemle toplamak için dinamik bir içe aktarma oluşturabilirsiniz:

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

Yakın zamanda, aktif gezinme bağlantılarını göstermek için bir şablon etiketi oluşturmak için buna benzer bir şey kullandım.


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

İşte your_main_appsizin settings.py dosyası yerleştirilir uygulama adıdır

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.