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.