Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A real example of URL Namespace

I am studying the Django documentation, but I encountered a part that I cannot understand: what is a real example of how use to use a namespace in a real problem. I know the syntax but I do not know the purpose of this.

like image 694
Rodrigo Pereira Avatar asked Oct 04 '13 01:10

Rodrigo Pereira


People also ask

What is a URL namespace?

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. Similarly, it also allows you to reverse URLs if multiple instances of an application are deployed.

What is name in Django URLs?

Django offers a way to name urls so it's easy to reference them in view methods and templates. The most basic technique to name Django urls is to add the name attribute to url definitions in urls.py .


2 Answers

Typically, they are used to put each application's URLs into their own namespace. This prevents the reverse() Django function and the {% url %} template function from returning the wrong URL because the URL-pattern name happened to match in another app.

What I have in my project-level urls.py file is the following:

from django.conf.urls.defaults import * from django.conf import settings from django.contrib import admin admin.autodiscover()  urlpatterns = patterns('',     url(r'^$', 'main.views.main', name='main'),     url(r'^login$', 'django.contrib.auth.views.login', name="login"),     url(r'^logout$', 'django.contrib.auth.views.logout',         {"next_page": "/"}, name="logout"),  # Admin     url(r'^admin/doc/', include('django.contrib.admindocs.urls')),     url(r'^admin/', include(admin.site.urls)), )  # Auto-add the applications. for app in settings.LOCAL_APPS:     urlpatterns += patterns('',         url(r'^{0}/'.format(app), include(app + '.urls', namespace=app)),     ) 

Note the last section: this goes through the applications I have installed (settings.LOCAL_APPS is a setting I added that contains only my apps; it gets added to INSTALLED_APPS which has other things like South), looks for a urls.py in each of them, and imports those URLs into a namespace named after the app, and also puts those URLs into a URL subdirectory named after the app.

So, for example, if I have an app named hosts, and hosts/urls.py looks like:

from django.conf.urls.defaults import *  urlpatterns = patterns('hosts.views',     url(r'^$', 'show_hosts', name='list'), ) 

Now my views.py can call reverse("hosts:list") to get the URL to the page that calls hosts.views.show_hosts, and it will look something like "/hosts/". Same goes for {% url "hosts:list" %} in a template. This way I don't have to worry about colliding with a URL named "list" in another app, and I don't have to prefix every name with hosts_.

Note that the login page is at {% url "login" %} since it wasn't given a namespace.

like image 98
Mike DeSimone Avatar answered Sep 30 '22 20:09

Mike DeSimone


Consider you are using a url pattern as below
url(r'^login/',include('app_name', name='login'))

Also Consider you are using a third-party app like Django-RestFramework. When you use the app, you have to declare the following line in URLs conf file of the project.

url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) 

Now if you check the code of rest-framework, you will find the below code in urls.py file

urlpatterns = [     url(r'^login/$', login, login_kwargs, name='login'),     url(r'^logout/$', logout, name='logout'), ] 

We have used 'login' name for a URL pattern in our project and the same name is being used by Django-rest-framework for one of their URL patterns. When you use reverse('login'), Django will get confused.
To resolve these kinds of issues, we use namespace.

@register.simple_tag def optional_docs_login(request):     """     Include a login snippet if REST framework's login view is in the URLconf.     """     try:         login_url = reverse('rest_framework:login')     except NoReverseMatch:         return 'log in' 

URL names of a namespace will never collide with other namespaces.
A namespaced URL pattern can be reversed using
reverse('namespace:url_name')

like image 27
nikhil ponnuru Avatar answered Sep 30 '22 18:09

nikhil ponnuru