user10406248
user10406248

Reputation: 13

Unable to resolve URL string for path using name with reverse

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

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

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

Exprator
Exprator

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

Related Questions