SyntaxStudy
Sign Up
Django Namespaces and include()
Django Beginner 1 min read

Namespaces and include()

URL namespaces prevent name collisions when multiple apps define URLs with the same name. There are two levels of namespace: application namespace (set via app_name in the app's urls.py) and instance namespace (set as the namespace argument to include()). When reversing a namespaced URL you prefix the name with the namespace: reverse('blog:post-list') or {% url 'blog:post-list' %} in a template. The include() function is how you attach an app's URLconf to a prefix in the root urls.py. It accepts either a dotted module path string or a tuple of (urlpatterns, app_name). When include() is used with a prefix, that prefix is prepended to every URL pattern in the included module. This makes it trivial to mount the same app at different URL prefixes in different projects. include() also accepts a list of URL patterns directly, which is useful for grouping related patterns without creating a separate urls.py file. For large projects you can nest includes multiple levels deep — the root URLconf includes each app's URLconf, and each app's URLconf can include further sub-modules. Django flattens this tree when building the URL resolver.
Example
# blog/urls.py — application namespace defined here
from django.urls import path
from . import views

app_name = 'blog'

urlpatterns = [
    path('',            views.PostListView.as_view(),   name='post-list'),
    path('<int:pk>/',   views.PostDetailView.as_view(), name='post-detail'),
    path('create/',     views.PostCreateView.as_view(), name='post-create'),
]

# accounts/urls.py
from django.urls import path
from . import views

app_name = 'accounts'

urlpatterns = [
    path('register/', views.RegisterView.as_view(), name='register'),
    path('profile/',  views.ProfileView.as_view(),  name='profile'),
]

# mysite/urls.py — root URLconf
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/',    admin.site.urls),
    path('blog/',     include('blog.urls')),      # app_name sets namespace
    path('accounts/', include('accounts.urls')),
    path('auth/',     include('django.contrib.auth.urls')),
]

# Reversing namespaced URLs in views
from django.urls import reverse
from django.shortcuts import redirect

def my_view(request):
    return redirect(reverse('blog:post-list'))

# Reversing in templates
# {% url 'blog:post-detail' pk=post.pk %}
# {% url 'accounts:register' %}