Як я можу побачити поточні URL-схеми, на які дивиться "зворотний"?
Я закликаю зворотний погляд в аргументі, який, на мою думку, повинен працювати, але не робить. Будь-який спосіб я можу перевірити, що там є, і чому мій шаблон не є?
Як я можу побачити поточні URL-схеми, на які дивиться "зворотний"?
Я закликаю зворотний погляд в аргументі, який, на мою думку, повинен працювати, але не робить. Будь-який спосіб я можу перевірити, що там є, і чому мій шаблон не є?
Відповіді:
Якщо ви хочете переглянути список усіх URL-адрес у своєму проекті, спочатку вам потрібно встановити розширення django , додати його до таких налаштувань:
INSTALLED_APPS = (
...
'django_extensions',
...
)
А потім запустіть цю команду у своєму терміналі
./manage.py show_urls
Для отримання додаткової інформації ви можете переглянути документацію.
TypeError: unsupported operand type(s) for +: 'NoneType' and 'str'
django_extensions
до вашого INSTALLED_APPS
після установки
Спробуйте це:
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()
set(v[1] for k,v in get_resolver(None).reverse_dict.items())
django.core.urlresolvers
було видалено в Django 2.0 , замініть імпортну лінію наfrom django.urls import get_resolver
Я перевірив інші відповіді в цій публікації, і вони або не працюють з 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
yield acc + [str(l.pattern)]
рядок на yield acc + [str(l.pattern)], l.callback
. Майте на увазі, що вона поверне функцію перегляду себе, а не ім'я
Django 1,11, Python 2.7.6
cd to_your_django_project
оболонка python Manag.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)
, і я іноді отримував "None" на початку деяких URL-адрес.
Є рецепт на 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)
show_urls(urls.url_patterns)
.
ModuleNotFoundError: No module named 'urls'
, не знаю чому?
test.py
в корені мого проекту і має цю помилку, також якщо я роблю import urls
в інтерпретаторі, то я також отримую цю помилку.
import urls
це місцевий імпорт, тому вам, мабуть, потрібно це зробити from app_name import urls
.
Я використовую наступну команду:
(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 | {} |
----------------------------------------------------------------------------------------------------
print
. Замість використання self.stdout.write
. docs.djangoproject.com/en/1.10/howto/custom-management-commands
Я використовую плагін: https://github.com/django-extensions/django-extensions , у ньому є команда show_urls, яка могла б допомогти.
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 Manag.py
import urls
get_resolved_urls(urls.urlpatterns)
У Django 3.0 це так просто, як:
from django.urls import get_resolver
print(get_resolver().url_patterns)
Друкує:
[<URLPattern '' [name='home']>, <URLPattern '/testing' [name='another_url']>]
Я розширив команду 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
в старих версіях.
Оновлення: Нова версія з OrdersDict тепер живе в пакеті django-:: https://github.com/5monkeys/django-bananas/blob/master/bananas/management/commands/show_urls.py
Просто введіть URL-адресу, який ви знаєте, не існує, і сервер поверне повідомлення про помилку зі списком шаблонів URL-адрес.
Наприклад, якщо ви запускаєте сайт за адресою http: // localhost: 8000 /
Введіть
http: // localhost: 8000 / something / blahNonsense , і ваш сервер поверне список пошуку URL-адреси та відобразить його у браузері
Мінімалістське рішення для джанго 2.0
Наприклад, якщо ви шукаєте URL-адресу, що знаходиться в першому додатку install_apps, ви можете отримати доступ до нього так:
from django.urls import get_resolver
from pprint import pprint
pprint(
get_resolver().url_patterns[0].url_patterns
)
get_resolver
з django.core.urlresolvers
. Дякую Марсіо!
Django 1.8, Python 2.7+ + Просто запустіть ці команди у своїй оболонці. Оболонку Python Manag.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)
Ви можете створити динамічний імпорт, щоб зібрати всі шаблони 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()
Нещодавно я щось подібне використовував для створення тегу шаблону для показу активних навігаційних посилань.
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_app
назва програми, де розміщено файл settings.py