Django: Bagaimana saya bisa melihat daftar pola url?

130

Bagaimana saya bisa melihat pola url saat ini yang melihat "terbalik"?

Saya menelepon terbalik dalam pandangan dengan argumen yang menurut saya harus berhasil, tetapi tidak. Dengan cara apa pun saya dapat memeriksa apa yang ada di sana dan mengapa pola saya tidak?

interstar
sumber
Aktifkan mode DEBUG dan lihat daftar URL di keluaran debug?
boatcoder

Jawaban:

181

Jika Anda menginginkan daftar semua url dalam proyek Anda, pertama-tama Anda perlu menginstal django-extensions , tambahkan ke pengaturan Anda seperti ini:

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

Dan kemudian, jalankan perintah ini di terminal Anda

./manage.py show_urls

Untuk informasi lebih lanjut, Anda dapat memeriksa dokumentasi.

robert
sumber
3
Sebenarnya saya salah, fitur ini sama sekali tidak disediakan oleh django.
robert
Yang saya dapatkan dari itu adalahTypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
Paul Tomblin
6
NB: Anda harus menambahkan django_extensionsuntuk Anda INSTALLED_APPSmenginstal setelah
Owen
80

Coba ini:

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

Atau jika Anda masih di Django 1. *:

from django.core.urlresolvers import get_resolver
get_resolver(None).reverse_dict.keys()
SmileyChris
sumber
9
ini mengembalikan fungsi tampilan, bukan url
Ronen Ness
3
Untuk mengembalikan url, lakukan ini sebagai gantinya: set (v [1] untuk k, v di get_resolver (None) .reverse_dict.iteritems ())
kloddant
4
Atau untuk python3:set(v[1] for k,v in get_resolver(None).reverse_dict.items())
Privat
6
django.core.urlresolverstelah dihapus di Django 2.0 , ganti baris impor denganfrom django.urls import get_resolver
hoefling
2
ini tidak berfungsi lagi untuk saya, hanya mengembalikan sebagian kecil url dalam proyek saya
J__
33

Django> = 2.0 solusi

Saya menguji jawaban lain dalam posting ini dan mereka tidak bekerja dengan Django 2.X, tidak lengkap atau terlalu rumit. Karena itu, inilah pendapat saya tentang ini:

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

Kode ini mencetak semua URL, tidak seperti beberapa solusi lain, kode ini akan mencetak jalur lengkap dan tidak hanya node terakhir. misalnya:

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
Cesar Canassa
sumber
1
Bagaimana saya bisa melakukannya jika ingin mendapatkan url dan nama tampilan ... Karena saya, saya ingin mendapatkan nama tampilan dan pola seperti hasil Anda ... Tolong bagaimana?
Nathan Ingram
@NathanIngram Tampilan disimpan dalam properti "callback" dari objek URLPattern, sehingga Anda bisa mengubah yield acc + [str(l.pattern)]baris ke yield acc + [str(l.pattern)], l.callback. Perlu diingat bahwa ini akan mengembalikan fungsi tampilan itu sendiri dan bukan nama
Cesar Canassa
Saya mendapatkan kesalahan: --- >>>> TypeError: item urutan 0: contoh str yang diharapkan, daftar ditemukan
Nathan Ingram
@NathanIngram The "print (''. Join (p))" tidak akan berfungsi karena sekarang ini adalah daftar tupel, bukan daftar string, coba "print (''. Join (p [0]))".
Cesar Canassa
22

Django 1.11, Python 2.7.6

cd to_proyek_django_anda

python manage.py shell

Kemudian tempel kode berikut.

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)

Output sampel:

^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/^(.+)/$
...
mamalia kecil
sumber
Ini adalah jawaban yang berhasil untuk saya, meskipun saya harus menambahkan Noneke baris urls = urlresolvers.get_resolver(None), dan terkadang saya mendapatkan 'Tidak Ada' di awal beberapa URL.
Chris
17

Ada resep di 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)
pmav99.dll
sumber
1
Baris terakhir itu seharusnya show_urls(urls.url_patterns).
Daniel Quinn
1
Saya mendapatkan ModuleNotFoundError: No module named 'urls', tidak tahu mengapa?
Alexey
1
@Alexey Ini adalah sesuatu yang mungkin ada hubungannya dengan django 2. Bisakah Anda mengkonfirmasi hal ini agar saya dapat memperbarui jawabannya?
pmav99
Saya telah menempatkan kode ini di file test.pydi root proyek saya dan mengalami kesalahan ini, juga jika saya lakukan import urlsdi interpreter maka saya juga mendapatkan kesalahan ini.
Alexey
Ini bukan masalah Django 1 vs 2: import urlsini adalah impor lokal, jadi Anda mungkin perlu melakukannya from app_name import urls.
Aaron Klein
16

Saya menggunakan perintah selanjutnya:

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

Pemakaian:

./manage.py showurls

Output sampel:

----------------------------------------------------------------------------------------------------
| ^(.+)/$              |                      | 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 | {} |
----------------------------------------------------------------------------------------------------
PADYMKO
sumber
4
Perhatikan bahwa dokumen menyarankan Anda untuk tidak menggunakan print. Sebagai gantinya gunakan self.stdout.write. docs.djangoproject.com/en/1.10/howto/custom-management-commands
Dustin Wyatt
Saya perlu melihat / mengurutkan berdasarkan namespace dan juga melihat semua bagian url, jadi perluas perintah ini di stackoverflow.com/a/42388839/179581
Andrei
1
@Andrei, jika Anda telah membuat keluaran dari jawaban Anda, itu akan memberi pengguna lain kemampuan untuk melihat manfaat dari metode Anda pada saya
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

Dalam python manage.py shell

import urls
get_resolved_urls(urls.urlpatterns)
Sandeep
sumber
4

Di Django 3.0, semudah:

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

Cetakan: [<URLPattern '' [name='home']>, <URLPattern '/testing' [name='another_url']>]

Cameron Sima
sumber
3

Saya telah memperpanjang perintah Seti untuk menampilkan namespace, semua bagian url, lebar kolom penyesuaian otomatis, diurutkan berdasarkan (namespace, nama): 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()

Catatan: urutan kolom disimpan di Python 3.6 dan harus digunakan OrderedDictdi versi yang lebih lama.

Pembaruan: Versi baru dengan OrderedDict sekarang ada di paket django-🍌s: https://github.com/5monkeys/django-bananas/blob/master/bananas/management/commands/show_urls.py

Andrei
sumber
1
dari django.conf.urls import RegexURLPattern, RegexURLResolver tidak lebih valid di django> 2.0 Tapi saya mengadaptasi intinya dan wroks sekarang, thx
cwhisperer
Saya sendiri menghadapi masalah ini baru-baru ini dan memperbarui intinya. Seseorang akan perlu menggunakan revisi sebelumnya untuk dijalankan pada Django <2.0.
Andrei
2

Solusi minimalis untuk django 2.0

Misalnya, jika Anda mencari url yang ada di aplikasi pertama dari instal_apps, Anda dapat mengaksesnya seperti itu:

from django.urls import get_resolver
from pprint import pprint

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

sumber
Bekerja untuk Django 1. * juga jika Anda mengimpor get_resolverdari django.core.urlresolvers. Terima kasih Marcio!
Fernando Costa Bertoldi
2

Django 1.8, Python 2.7+ Jalankan saja perintah ini di Shell Anda. Python manage.py shell dan jalankan kode berikut.

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)
Aditya Saini
sumber
1
Bisakah Anda memberikan detail lebih lanjut tentang jawaban Anda?
toshiro92
1
Saya telah mengedit jawaban saya, Anda harus menjalankan ini di cangkang Anda.
Aditya Saini
0

Anda dapat membuat impor dinamis untuk mengumpulkan semua Pola URL dari setiap aplikasi dalam proyek Anda dengan metode sederhana seperti:

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

Saya baru-baru ini menggunakan sesuatu seperti ini untuk membuat tag template untuk menampilkan link navigasi yang aktif.

ViaTech
sumber
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

Berikut your_main_appadalah nama aplikasi tempat file settings.py Anda ditempatkan

nazmul_94_hasan
sumber