[Fixed]-What is difference between instance namespace and application namespace in django urls?

30👍

Think of instance namespace as your nickname and application namespace as your real name.

People can have many nicknames for you, but your real name doesn’t change.

Django uses the application namespace (your real name) to reverse urls, cause as an application you should not care how many instance namespaces (nicknames) there are.

But to differentiate between one instance and the next, you will use the instance namespaces (nicknames) in urlconfs.

Let’s say your app deals with customers and store employees. Both of these have physical addresses and you might want to use an app that just handles all address information: forms, validation, model structure, geo location etc. Our fictional app is a reusable django app called "django_super_address".

Your root url conf may look like this:

urlpatterns = [
    path('customer/address/',
         include('django_super_address.urls',
         namespace='customer_address')
    ),
    path('employee/address/',
         include('django_super_address.urls',
         namespace='employee_address')
    ),
]

This includes the same urls below different URL paths, pointing to the same app, using different namespaces (nicknames).

Within django_super_address, it has defined it’s application namespace:

# File: django_super_address/urls.py
from . import views
app_name = 'django_super_address'

urlpatterns = [
    path('create/', views.SomeAddressCreateView.as_view(),
         name='address_create'),
    path('create/success/', views.SuccessView(),
         name='address_create_success'),
    ...
]

And in views it uses:

# File django_super_address/views.py
class SomeAddressCreateView(generic.CreateView):
    def success_url(self):
        return reverse(
           'django_super_address:address_create_success'
        )
    ...

When Django gets the URL `/employee/address/create/’:

  1. It sets the instance namespace to employee_address
  2. It reads the urls from django_super_address
  3. It sets the application namespace to django_super_address and
    associates the urls.py with that application namespace.

In the view:

  1. It reverses the URL by looking at the urls file associated with the application namespace (real name) and reverses the name into: create/success
  2. It then goes back up the chain, now using the instance namespace (nickname) to prepend the rest of the url: root + employee/address/ + create/success/ = /employee/address/create/success/

And there you have it: nicknames for urlconfs and application namespaces for reverse!

6👍

From my understanding, it goes like this:

  • For two different applications using the same URL pattern, use an Application namespace.
  • For two different instances of the same application using the same URL configuration and views, use an Instance namespace.

The application of Instance namespace might sound a bit confusing. Let me try to clarify if that’s the case. Consider the example given in the Django docs.

urls.py:

from django.urls import include, path

urlpatterns = [
path('author-polls/', include('polls.urls', namespace='author-polls')),
path('publisher-polls/', include('polls.urls', namespace='publisher-polls')),
]

polls/urls.py:

from django.urls import path

from . import views

app_name = 'polls'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
...
]

The namespaces are defined like this:

  • The Application namespace is defined by app_name attribute in polls/urls.py
  • The Instance namespace is defined by namespace argument in urls.py

Here, both author-polls and publisher-polls are using the same polls.urls to resolve their URLs. Without an Instance namespace, resolving a URL like ‘polls:index’ could create confusion on which URL it’s intending to fetch. That’s why Django has a set of protocol defined to fix this issue for all kinds of situations when you are attempting to reverse and resolve namespaced URLs.

1👍

The namespace instance can only be used with include. This is useful when we want to have multiple paths with different URLs, but we want to include the same URLconf modules.

Let’s say we have this code:

#my_site/urls.py
urlpatterns = [
path('url1/',include('english.urls')),
path('url2/',include('english.urls'))]

#english/urls.py
app_name='english'
urlpatterns = [
path('words/', views.index, name='words')]

#template.html
<a href="{% url 'english:words' %}">Something</a>

Clicking on the link will redirect us to url1/words, because Django will choose the first element from the urlpatterns. If we want to be redirected to url2/words, we must use the namespace (instance namespace), that is:

#my_site/urls.py
urlpatterns = [
path('url1/',include('english.urls', namespace='eng')),
path('url2/',include('english.urls', namespace='eng2'))]

#english/urls.py
app_name='english'
urlpatterns = [
path('words/', views.index, name='words')]

and then:

#template.html
<a href="{% url 'eng2:words' %}">Something</a>

I will add that if we do not have an instance namespace, Django will probably warn us:

WARNINGS: ?: (urls.W005) URL namespace ‘english’ isn’t unique. You may
not be able to reverse all URLs in this namespace

In general, the instance namespace is useful when, for example:

  • we want to have different URLs depending on the user’s native language, such as: ‘django/documentation/’, ‘django/dokumentacja/’ or ‘django/en’, ‘django/pl’
  • we want to separate URLs for specific groups of people: ‘amazon/clients/’, ‘amazon/employees’
  • we have changed the URL of the website and to not confuse old users, we also allow access to the site via the previous link
  • we make it easier to find our site on the internet

This is not limited to different URLs. Even though we use the same views, we can slightly modify them depending on the URL we are on:

def index(request):
    current_url = request.path
    if current_url == '/url1/words/':
        ''' do something '''
    elif current_url == '/url2/words/': 
        ''' do something else '''
    return render(request, 'template.html')

We can, for example, change the context or choose a different template.

0👍

You can use the urls.py for an app by including it in different urls path, for example we can have:

urlpatterns = [
    path('author-polls/', include('polls.urls')),
    path('publisher-polls/', include('polls.urls')), 
]

As you see, both included polls.urls which is:

app_name = 'polls' urlpatterns = [
    path('', views.IndexView.as_view(), name='index'),
    path('<int:pk>/', views.DetailView.as_view(), name='detail'),
    ... 
]

So far so good!

But there is a problem. In the template, where is ‘polls:index’ pointing?!
And now instance namespace comes into the picture.

urlpatterns = [
    path('author-polls/', include('polls.urls', namespace='author-polls')),
    path('publisher-polls/', include('polls.urls', namespace='publisher-polls')), 
]

Django has some rules to reverse namespace urls >> https://docs.djangoproject.com/en/3.0/topics/http/urls/#reversing-namespaced-urls

0👍

basically each application namespace can have multiple instance namespace ,
for example :

this is project URLs file (main urls) :

path('', include("movie_app.urls")),
path('my_namespace1/', include("movie_app.urls", namespace='my_namespace1')),
path('my_namespace2/', include("movie_app.urls", namespace='my_namespace2')),

you can see, they all mentions to the same app.urls file (movie_app.urls) , but the path link are different .

first one is : "",

and second one is : "my_namespace1/",

and the third is : "my_namespace2/",

and this is movie_app.urls file (child file ) :

app_name = 'movie_app'

urlpatterns = [
    path('appmovie1/', myview1 , name="myname"),   

]

now when you use the all paths in your html templates for example :

    <h1><a href="{% url 'movie_app:myname' %}"> application namespace : url name</a></h1>
    <h1><a href="{% url 'my_namespace1:myname' %}">instance namespace1 : url name</a></h1>
    <h1><a href="{% url 'my_namespace2:myname' %}">instance namespace2 : url name </a></h1>
  

you will note the different in href link :

    <h1><a href="/appmovie1/"> application namespace : url name</a></h1>
    <h1><a href="/my_namespace1/appmovie1/">instance namespace1 : url name</a></h1>
    <h1><a href="/my_namespace2/appmovie1/">instance namespace2 : url name </a></h1>
  

in the end:

app namespace and instance name space will help you to determine / select the correct URL path from multiple URL paths that use same include .urls file.

I hope this helpful for you .

👤K.A

Leave a comment