skip to content

In Django, what is the difference between the app_name set in an app's urls.py and the namespace argument passed to include()?

level: middleimportance: must knowfreq 52%

answer

  1. two halves of a URL namespace
  2. shared by every mount
  3. unique per mount
  4. what the second defaults to
  5. colon-separated lookups

basics

~20 s

app_name is the application namespace, shared by every mount of that URLconf; include(..., namespace=...) is the instance namespace, identifying one mount. The instance defaults to app_name, and routes are looked up as 'namespace:name', such as 'comments:detail'.

solid answer

~40 s

Without namespaces every route name is global, so two apps that both name a route `list` collide and `reverse()` finds whichever pattern is last. Setting `app_name = 'comments'` in `comments/urls.py` puts its names under the **application namespace** `comments`, so code writes `'comments:detail'`. The `namespace=` argument to `include()` sets the **instance namespace**, which names one particular mount and must be unique in the project; when omitted it defaults to `app_name`, making that mount the default instance. Passing `namespace=` without any `app_name` raises `ImproperlyConfigured`; the app name can also come from an `include((patterns, 'comments'))` tuple. `request.resolver_match.app_name` and `.namespace` show both halves for the current request, and namespaces nest, as in `'forum:comments:detail'`.

go deeper

for a junior

Recall that app_name in an app's urls.py lets you write names like 'comments:detail', and that this avoids clashes between apps.

for a middle

Explain application versus instance namespace, the default of one to the other, the ImproperlyConfigured rule, and how nested lookups like 'forum:comments:detail' work.

for a senior

Keep reusable apps on their application namespace, catch W005 duplicate instances, and debug 'not a registered namespace' errors back to a missing app_name or include().

for a principal

Make app_name part of each app's public contract, since renaming it breaks every template and reverse() call in projects that mount the app.

## Why namespaces exist In Django, a route's `name=` is how code and templates build its URL. Without namespaces those names share one global pool. If the comments app names a route `list` and the events app does too, Django's documentation is explicit: the URL that `reverse()` finds depends on whichever pattern is last in the project's `urlpatterns`. Prefixing names by hand, such as `comments-list`, reduces the risk; **URL namespaces** remove it. ## The two halves A Django URL namespace has two parts, both strings: | Part | Set by | Scope | Example | |---|---|---|---| | **Application namespace** | `app_name` in the included URLconf, or the second item of an `include((patterns, app_name))` tuple | every mount of that URLconf | `comments` | | **Instance namespace** | `include(..., namespace='...')` | one mount; should be unique project-wide | `news-comments` | The application namespace says **which app** a route belongs to. The instance namespace says **which deployment** of it. When `namespace=` is omitted, the instance namespace defaults to the application namespace, and an instance whose instance namespace equals the app name is that app's **default instance**. ## Setting them 1. **The usual way:** `app_name = 'comments'` next to `urlpatterns` in `comments/urls.py`, and `path('comments/', include('comments.urls'))` in the root. Application namespace and instance namespace are both `comments`. 2. **Without a module:** `include((comment_patterns, 'comments'))`, useful when patterns are built in code. 3. **A named mount:** `include('comments.urls', namespace='news-comments')`. This requires an application namespace from one of the forms above; otherwise Django raises `ImproperlyConfigured`, saying a namespace without an `app_name` is not supported. 4. **The admin:** `admin.site.urls` supplies both at once, `admin` as the app and the site's name as the instance. ## Looking names up - A namespaced route is addressed with a colon: `'comments:detail'`. A bare `'detail'` searches only the global names and does not find it. - Namespaces nest. If a `forum` URLconf with `app_name = 'forum'` includes the comments URLconf, its routes are `'forum:comments:detail'`. - The first part of a lookup is tried as an application namespace, which may resolve to one of several instances; if no app has that name, it is tried as an instance namespace directly. - For the current request, `request.resolver_match.app_name` and `request.resolver_match.namespace` report the full application and instance namespaces, colon-joined when nested. ```python # comments/urls.py from django.urls import path from . import views app_name = 'comments' urlpatterns = [ path('', views.comment_list, name='list'), path('<int:pk>/', views.comment_detail, name='detail'), ] ``` ```python # a view elsewhere in the project from django.urls import reverse url = reverse('comments:detail', kwargs={'pk': 42}) # '/comments/42/' ``` ## Pitfalls - **Forgetting `app_name`.** Code that reverses `'comments:list'` then fails with `NoReverseMatch: 'comments' is not a registered namespace`. - **`namespace=` without `app_name`.** Raises `ImproperlyConfigured` when the URLconf loads. - **Reusing an instance namespace.** Two mounts with the same instance namespace trigger system check `urls.W005`, which warns that not every URL in it can be reversed. - **Writing the instance name inside the app.** A reusable app should reverse `'comments:...'`, its application namespace, and let Django pick the instance, never hardcode `'news-comments:...'`. - **Assuming the module path is the namespace.** Django never derives a namespace from `comments.urls`; only `app_name` or the tuple sets one. ## Diagnosing namespace errors The messages Django raises map directly to a cause: | Message or check | Usual cause | |---|---| | `NoReverseMatch: 'comments' is not a registered namespace` | the URLconf has no `app_name`, is not included, or is included from a different root URLconf | | `... is not a registered namespace inside 'forum'` | a nested lookup names an inner namespace the outer URLconf does not include | | `ImproperlyConfigured` about a namespace without an `app_name` | `namespace=` passed for a URLconf that sets no application namespace | | `urls.W005` namespace isn't unique | the same instance namespace used for two mounts | When the message names a namespace, check the included module first: an `app_name` line deleted or misspelled in a refactor is the most common cause. ## Choosing names Use the app's label as `app_name`, keep it stable because templates across the project depend on it, and reserve `namespace=` for the cases where the same URLconf is mounted more than once.

  • In Django, how does code inside a view find out which namespace served the current request?
    Django sets `request.resolver_match` during resolution. Its `app_name` holds the application namespace, `namespace` the instance namespace, and `namespaces` the list of parts when namespaces are nested. A view shared by two mounts can use `namespace` to decide, for example, which section's comments to show.
  • What is a default instance in Django's URL namespaces?
    It is the mount whose instance namespace equals the application namespace, which is what you get by including a URLconf with `app_name` and no `namespace=` argument. When a lookup such as `'comments:list'` has no current instance to go by, Django prefers the default instance.

saying these in an interview costs you the question

  • When namespace= is omitted, the instance namespace defaults to the module path 'comments.urls'.
  • include(..., namespace='x') works fine without any app_name.
  • A bare 'detail' still finds a route that lives inside the comments namespace.
  • Two apps can both name a route 'list' without namespaces and reverse() will raise an error.
  • A reusable app should reverse its own URLs by their instance namespace.