Reputation: 13
I have been spending the better part of my week learning Django to build my website and I've stumbled upon an issue I can't seem to get working. I wish to resolve a URL string for a path by including with that path a particular name and then being able to reference that name down the line. This works fine until I change the route in path to use the include method.
First Attempt:
from django.url import include, path
from . import views
urlpatterns = [
path('testapp/', include('testapp.urls'), name='testapp'),
path('about/', views.about, name='about'),
]
Now when I call {% url 'about' %}
from my template html file I get back '/about/'
as expected but when I try and call {% url 'testapp' %}
I get a NoReverseMatch
exception instead of getting '/testapp/'
. After digging through the documentation I stumbled upon this example that shows path with include using a namespace instead so I adapted the above a bit.
Second Attempt:
# 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'),
]
Now from the previous example I try using the namespace in lieu of a name {% url 'testapp' %}
and I again get the same NoReverseMatch
exception however using the namespace and name from my included url {% url 'testapp:directory' %}
does work giving me '/testapp/directory/'
.
I know there's some concept I'm not getting or something I'm overlooking but I'm just running around in circles at this point and would really appreciate any help somebody could afford me.
If it helps I'm trying to get the path so that I can use it in a navigation bar to highlight the currently activated tab. I'm also not hardcoding the paths as I'm trying to keep it DRY although at this point if I can't get it done I might have to but I'm hoping someone has a much better idea of what they're doing and could point me in a helpful direction. I appreciate all assistance and thank you!
Upvotes: 1
Views: 283
Reputation: 476594
The problem is that testapp
is not a single view: it is an include(..)
, so it encapsulates a collection of views:
from django.url import include, path
from . import views
urlpatterns = [
path('testapp/', include('testapp.urls'), name='testapp'),
path('about/', views.about, name='about'),
]
It is not said that this collection contains a view at all, or it can contain multiple. Even if it only contains a single view, then it would be unsafe since you can later change your mind, and add an extra view.
If there are two or more views, then how will you decide what view (and therefore URL) to take? If the include(..)
has two views: the "homepage" and the profile page, then this makes a significant difference.
You thus should refer to a real name, and whether you give the include(..)
a namespace in the include(..)
is irrelevant:
{% url 'testapp_name:testapp_index' %} <!-- first attempt -->
{% url 'testapp:testapp_index' %} <!-- second attempt -->
To reference the name of a real view.
Upvotes: 1
Reputation: 27503
{% url 'testapp_name:testapp_index' %}
or
{% url 'testapp_name:testapp_directory' %}
as you are using app_name
in the urls file, you need to mention it with the name of the view
Upvotes: 1