我怎么能看到当前的urlpatterns“反向”正在寻找?

我在一个视图中调用了逆向,我认为这个论证应该成立,但实际上并不成立。有什么办法能让我知道为什么我的图案没有?


当前回答

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

其他回答

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

如果你正在使用DRF,你可以通过从router.get_urls()(在你的Django应用的urls.py文件中)打印特定路由器的urlpatterns来打印所有的URL模式。

打开你的apps urls.py,并在文件底部添加打印语句,这样整个文件看起来就像这样:

import pprint

from django.urls import include, path
from rest_framework import routers

from . import views

router = routers.DefaultRouter()
router.register(r"users", views.UserViewSet, basename="User")
router.register(r"auth", views.AuthenticationView, basename="Auth")
router.register(r"dummy", views.DummyViewSet, basename="Dummy")
router.register("surveys", views.SurveyViewSet, basename="survey")

urlpatterns = [
    path("", include(router.urls)),
]

pprint.pprint(router.get_urls())

然后,这些图案会像这样打印出来:

[<URLPattern '^users/$' [name='User-list']>,
 <URLPattern '^users\.(?P<format>[a-z0-9]+)/?$' [name='User-list']>,
 <URLPattern '^users/admins/$' [name='User-admins']>,
 <URLPattern '^users/admins\.(?P<format>[a-z0-9]+)/?$' [name='User-admins']>,
 <URLPattern '^users/current/$' [name='User-current']>,
 <URLPattern '^users/current\.(?P<format>[a-z0-9]+)/?$' [name='User-current']>,
 <URLPattern '^users/(?P<pk>[^/.]+)/$' [name='User-detail']>,
 <URLPattern '^users/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='User-detail']>,
 <URLPattern '^auth/login/$' [name='Auth-login']>,
...
]

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

试试这个:

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

有一个我使用的插件:https://github.com/django-extensions/django-extensions,它有一个show_urls命令可以帮助。