URL Namespacing
URL namespacing in Django lets each app label its URL names with a unique prefix so that two apps can both have a URL called 'detail' without colliding — you set app_name in the app's urls.py and then refer to URLs as 'appname:urlname' when reversing them.
Learn URL Namespacing in our free Django course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Django course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll name your URL patterns, reverse them by name instead of hard-coding paths, then add an application namespace so several apps can coexist without their URL names clashing.
Every URL pattern can be given a name with the name= argument of path() . Once a pattern has a name, you never have to write its literal path again — you ask Django to build the path for you with reverse() in Python or the {' '} tag in templates.
This matters because paths change. If you hard-code /posts/5/ in fifty places and later move it to /articles/5/ , you have fifty edits. With a named URL you change the pattern once and every reverse() call follows along.
Names solve repetition, but they create a new problem: what if a blog app and a shop app both have a pattern named detail ? Django would not know which one you mean. The fix is an application namespace : set app_name at the top of the app's urls.py .
After that, every name in that app is addressed as 'appname:name' . You wire the app into the project with include('app.urls') , and Django picks up the app_name automatically.
Most useful URLs capture a value — a primary key, a slug, a page number. You pass these to reverse() through args (positional) or kwargs (by name), and to the {' '} tag as space-separated values after the name.
Fill in the blank so the lookup uses the correct namespaced name 'blog:detail' for the blog app's detail page.
❌ NoReverseMatch: Reverse for 'detial' not found
The name is misspelled, or you passed the wrong number of arguments for the pattern.
✅ Fix: check the exact spelling of name= and make sure your args match the captured parameters.
You set app_name = "blog" but still reverse the bare name 'detail' , so Django cannot find it.
✅ Fix: add the prefix — reverse 'blog:detail' instead of 'detail' .
❌ NoReverseMatch: keyword argument 'pk' not found
The number or names of the arguments you passed do not match the pattern's captured groups.
✅ Fix: pass exactly the values the pattern captures — for pass one value via args=[pk] or kwargs={' '} .
Build a mini resolver that registers named patterns for two apps and reverses them with arguments — exactly what Django does for you behind the scenes.
Lesson 15 complete — your URLs are namespaced and collision-proof!
You now know how to name URL patterns, reverse them with reverse() and the url tag, declare an app_name so apps never clash, and pass arguments to namespaced URLs without tripping NoReverseMatch.
🚀 Up next: The Messages Framework — show one-time success and error notices to your users.
Practice quiz
What problem does URL namespacing solve?
- It speeds up URL matching
- It compresses long URLs
- It hides URLs from search engines
- It lets two apps share a URL name like 'detail' without colliding
Answer: It lets two apps share a URL name like 'detail' without colliding. Namespacing prefixes names with the app, so identical names in different apps do not clash.
How do you give a URL pattern a name in path()?
- Pass it as the first positional argument
- Pass the name= argument, e.g. path('', views.index, name='index')
- Set it in settings.py
- Add a @name decorator to the view
Answer: Pass the name= argument, e.g. path('', views.index, name='index'). The name= argument of path() labels a pattern so it can be reversed by name.
Which function builds a URL path from a name in Python?
- post_detail
Answer: post_detail. reverse() turns a (namespaced) name plus args into the matching URL path.
How do you set an application namespace?
- With namespace= on every path()
- In the project's settings.py
- By setting app_name in the app's urls.py
- By naming the app folder with a colon
Answer: By setting app_name in the app's urls.py. Setting app_name in the app's urls.py declares the application namespace.
After setting app_name = 'blog', how do you reverse the 'detail' pattern?
- reverse('detail')
- reverse('blog:detail')
- reverse('detail:blog')
- reverse('blog.detail')
Answer: reverse('blog:detail'). Once app_name is set, the name must be prefixed: reverse('blog:detail').
Which template tag builds a URL from a namespaced name?
- {{ url 'blog:detail' }}
- {% reverse 'blog:detail' %}
- {% link 'blog:detail' %}
- {% url 'blog:detail' post.pk %}
Answer: {% url 'blog:detail' post.pk %}. The {% url 'blog:detail' post.pk %} tag builds the path from a namespaced name in templates.
How do you wire an app's URLs into the project urls.py?
- path('blog/', include('blog.urls'))
- path('blog/', 'blog.urls')
- include(path('blog/'))
- path('blog/', app_name='blog')
Answer: path('blog/', include('blog.urls')). You mount an app's URLs with include('blog.urls'); Django picks up its app_name automatically.
What does NoReverseMatch usually mean?
- The view returned None
- The template was not found
- Django could not match the name and arguments you passed to reverse()
- The database is unavailable
Answer: Django could not match the name and arguments you passed to reverse(). NoReverseMatch means no pattern matched the name/args — often a typo or missing namespace prefix.
How do you pass a captured value to reverse() for a pattern like <int:pk>?
- reverse('blog:detail', 5)
- blog:detail
Answer: blog:detail. Pass positional values via args=[5] (or kwargs={'pk': 5}) to fill the captured parameter.
What does the namespace argument of include() provide, versus app_name?
- An instance namespace, letting the same app be mounted multiple times under different prefixes
- A faster URL resolver
- A way to disable a URL pattern
- The same thing as name= on a path
Answer: An instance namespace, letting the same app be mounted multiple times under different prefixes. app_name is the application namespace; include()'s namespace= sets an instance namespace for mounting an app more than once.