Я потратил большую часть своей недели на изучение Django для создания своего веб-сайта, и я наткнулся на проблему, с которой, похоже, не могу работать. Я хочу разрешить строку URL для пути, включив в этот путь конкретное имя, а затем возможность ссылка с этим именем в конце строки. Это отлично работает, пока я не изменю маршрут в path, чтобы использовать метод include.

Первая попытка:

from django.url import include, path
from . import views

urlpatterns = [
    path('testapp/', include('testapp.urls'), name='testapp'),
    path('about/', views.about, name='about'),
]

Теперь, когда я вызываю {% url 'about' %} из своего html-файла шаблона, я возвращаю '/about/', как и ожидалось, но когда я пытаюсь вызвать {% url 'testapp' %}, я получаю исключение NoReverseMatch вместо {{X4 } } . Покопавшись в документации, я наткнулся на этот пример, который показывает путь с включением, используя вместо этого пространство имен, поэтому я немного адаптировал приведенное выше.

Вторая попытка:

# from mysite/urls.py (adapted from before)
from django.url import include, path
from . import views

urlpatterns = [
    path('testapp/', include('testapp.urls', namespace='testapp')),
    path('about/', views.about, name='about'),
]


#from testapp/urls.py
from django.url import include, path
from . import views

app_name = 'testapp_name'

urlpatterns = [
    path('', views.index, name='testapp_index'),
    path('directory/', views.directory, name='testapp_directory'),
]

Теперь из предыдущего примера я пытаюсь использовать пространство имен вместо имени {% url 'testapp' %} и снова получаю то же исключение NoReverseMatch, однако использование пространства имен и имени из моего включенного URL {% url 'testapp:directory' %} действительно дает мне '/testapp/directory/'.

Я знаю, что есть какая-то концепция, которую я не понимаю, или что-то, что я не замечаю, но сейчас я просто бегаю по кругу и буду очень признателен за любую помощь, которую кто-то может мне позволить.

Если это помогает, я пытаюсь получить путь, чтобы использовать его на панели навигации, чтобы выделить текущую активную вкладку. Я также не кодирую пути жестко, поскольку пытаюсь сохранить их DRY хотя на данный момент, если я не могу это сделать, мне, возможно, придется, но я надеюсь, что кто-то имеет гораздо лучшее представление о том, что они делают, и может указать мне полезное направление. Я ценю любую помощь и благодарю вас!

1
user10406248 24 Сен 2018 в 09:36

2 ответа

Лучший ответ

Проблема в том, что testapp не является отдельным представлением: это include(..), поэтому он инкапсулирует коллекцию представлений:

from django.url import include, path
from . import views

urlpatterns = [
    path('testapp/', include('testapp.urls'), name='testapp'),
    path('about/', views.about, name='about'),
]

Не сказано, что эта коллекция вообще содержит представление или может содержать несколько. Даже если он содержит только одно представление, это было бы небезопасно, так как позже вы можете передумать и добавить дополнительное представление.

Если есть два или более представления, то как вы решите, какое представление (и, следовательно, URL) выбрать? Если include(..) имеет два представления: "домашнюю страницу" и страницу профиля, то это имеет большое значение.

Таким образом, вы должны ссылаться на настоящее имя, и не имеет значения, даете ли вы include(..) пространство имен в include(..):

{% url 'testapp_name:testapp_index' %} <!-- first attempt -->
{% url 'testapp:testapp_index' %} <!-- second attempt -->

Для ссылки на имя реального представления.

1
Willem Van Onsem 24 Сен 2018 в 06:43
{% url 'testapp_name:testapp_index' %} 

Или

{% url 'testapp_name:testapp_directory' %}

Поскольку вы используете app_name в файле URL-адресов, вам необходимо упомянуть его вместе с именем представления

1
Exprator 24 Сен 2018 в 06:42