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.
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.
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 .
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.
Consider you are using a url pattern as belowurl(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')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With