Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is difference between instance namespace and application namespace in django urls?

I am referring https://www.webforefront.com/django/namedjangourls.html to understand django urlconfs. I have encountered terms instance namespace and application namespace. I know about namespaces in urlsconfs. But I don't know the difference between them.

I referred django docs for it. It mentions that instance and app namespaces, comes into picture, when multiple instances of same app is used in django project.

But still, I am not able to understand it. I have googled out, but couldn't find any help on it.

Thanks in advance.

like image 817
Mangu Singh Rajpurohit Avatar asked Mar 12 '18 14:03

Mangu Singh Rajpurohit


2 Answers

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!

like image 75
Melvyn Sopacua Avatar answered Sep 25 '22 15:09

Melvyn Sopacua


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.

like image 30
Dipesh J Pandey Avatar answered Sep 26 '22 15:09

Dipesh J Pandey