include()ing urlconf from the Django app to the project's
urls.py, some kind of app's name (or namespace) should be specified as:
include((pattern_list, app_namespace), namespace=None)in main
app_namevariable in app's
Since, I guess, Django 2, the second method is the preferred one Although I copy-pasted first function signature from Django 3 documentation. But that's not the main point.
My current understanding of
namespace parameter of
include() is that it's what I use when using
What is the purpose of
app_name in app's
app_namespace in main
Are these exactly the same thing?
How is it used by Django?
Existing questions (and answers) I've found here explain HOW I should specify it rather than WHY.
URL namespaces allow you to uniquely reverse named URL patterns even if different applications use the same URL names. It’s a good practice for third-party apps to always use namespaced URLs (as we did in the tutorial). Similarly, it also allows you to reverse URLs if multiple instances of an application are deployed. In other words, since multiple instances of a single application will share named URLs, namespaces provide a way to tell these named URLs apart.
For years, we've (at Django) been skirting around the (confusing) distinction between an application name(space) and an instance namespace. We've always just recommended using instance namespace, as per the examples in the docs.
What's happened with Django 2.0 (and onwards) is they've made it so you can't use an instance namespace without also (first) using an application name. Instead of fixing code, we should update our examples to the correct usage.
The include needs to go like this:
urlpatterns += [ url('API/', include((router.urls, 'pikachu')) ]
The tendency is to include the second
namespace='pikachu' instance namespace parameter as well, but that's not needed — it defaults to None and is set to
'pikachu' in this case automatically.
Generally, users want to be including an app-level URLs module explicitly setting the
app_name attribute there, rather than including the router by hand.
In this answer, I am taking the DRF package and its URL patterns. If you want to try any of the snippets mentioned in this answer, you must install (
pip install djangorestframework) and add
The application namespace can be set in two ways, [Ref: Django doc]
You can see that DRF has set the
urls.py. Django will use this
app_name as the application namespace only if we are included the patterns with module reference.
urlpatterns = [ path('drf-auth/bare/', include('rest_framework.urls')), ]
include((pattern_list, app_namespace), namespace=None) function using
In this method, you can set an additional
app_namespace for the application, if you want.
Most importantly, we are passing a pattern_list instead of module
from rest_framework.urls import urlpatterns as drf_urlpatterns urlpatterns = [ path('drf-auth/foo/', include((drf_urlpatterns, 'foo-app-namespace'))), ]
from django.urls import path, include, reverse from rest_framework.urls import urlpatterns as drf_urlpatterns urlpatterns = [ path('drf-auth/bare/', include('rest_framework.urls')), path('drf-auth/foo/', include((drf_urlpatterns, 'foo-app-namespace'))), path('drf-auth/bar/', include((drf_urlpatterns, 'bar-app-namespace'))), ] print(reverse('rest_framework:login')) print(reverse('foo-app-namespace:login')) print(reverse('bar-app-namespace:login')) #results /drf-auth/bare/login/ /drf-auth/foo/login/ /drf-auth/bar/login/
- What is the purpose of
Both are used to set the application namespace. The
app_name can be used as a default application namespace, if defined in the
- Are these exactly the same thing?
- How is it used by Django?
The application namespace and instance namespace are used to retrieve the URL path. In Django, whenever the
reverse(...) function get executed, Django looking for an application namespace first, than any other. You can read more about how Django resolve the URL here, Reversing namespaced URLs
app_name in app/urls.py and
include((pattern_list, app_namespace), namespace=None) in main urls.py are the same referenced as application namespace which describes the name of the application that is being deployed.
One can either pass the whole app/urls.py or a string reference of app/urls.py with app_name to
# blog.urls from django.urls import path from . import views app_name = 'blog' urlpatterns = [ path('', views.index(), name='index'), path('<int:pk>/', views.post(), name='detail'), ]
# project urls from django.urls import include, path urlpatterns = [ path('', include('blog.urls')), ]
a tuple of url patterns and app_namespace to
# project urls from django.urls import include, path from blog.urls import urlpatterns as blogpatterns urlpatterns = [ path('', include((blogpatterns, 'blog'))), ]
app_namespace will be the default application namespace when provided in
app_namespace is not provided, then it will look for
blog/urls.py and that will be the default namespace.
Without the app namespace, urls are added to global namespace which may lead to url conficts.