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

5

16

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.

Kalakalaazar answered 12/3, 2018 at 14:22 Comment(1)
Not sure what the question is but Django uses the namespace argument in the url conf to determine where the lookup should match the view function name i.e 'admin:index' admin being the application namespace as admin is an application in the django project. and index a view function in the views.py module. The namespace can be changed by default it uses the app module with the app_name or that can be added to the url.py in case of Django2.0 app_name = 'your_app_name'Liken
S
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!

Symposium answered 6/9, 2018 at 18:17 Comment(4)
The part I'm confused about is why would I have two url structures that point to the same app? This seems like such a niche use-case.Moonrise
If I may ask, why is admin:index the example used to answer this question everywhere else on the internet? Isn't index the view name not the instance namespace?Moonrise
I am trying to do drf Namespace versioning. I was missing app_name inside <app_name>/urls.py file. With this explanation I am able to understand and use it.Agan
Gave -1: I'd be much clearer if you stated that if you are not specifying instance namespace, and instead are using application namespace in the reverse, the LAST instance namespace will be used. Instead of stating that, you just say "now using the instance namespace to prepend [...]". That arises the confusion of "ok, but how does reverse know what instance namespace to use...?".Sized
D
7

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.

Diacritical answered 6/9, 2018 at 17:17 Comment(1)
This is incorrect. Especially "For two different applications using the same URL pattern, use an Application namespace.".Symposium
C
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.

Couscous answered 21/1, 2023 at 15:22 Comment(1)
"Clicking on the link will redirect us to url1/words, because Django will choose the first element from the urlpatterns.". Django will choose the last appeared instance of the app which is url2/words. Am I right?Fy
R
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

Rebane answered 8/2, 2020 at 18:42 Comment(0)
Z
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 .

Zionism answered 13/8, 2021 at 3:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.