= URLNamespacing = == Usecases == The following usecases are those imagined by the author of this document (Florian) and do not necessarily represent the original intentions. That said, they should provide an overview of the available functionality, beeing best pratices or not… * Multiple deployments of a single App (like the admin) * Prevention of name clashes between view names (This was originally not intended) == Analysis of URL namespaces == URL namespaces currently work as follows: Every include() in an URLConf defines an application and an instance namespace. The application namespace is the name of the 'app' ie 'admin' whereas the instance namespace designates the specific deployment of the adminpage, ie 'admin1' or 'admin2': {{{#!python urlpatterns = [ url('^admin1/', include(admin_urls, namespace='admin1', app_name='admin'), url('^admin2/', include(admin_urls, namespace='admin2', app_name='admin'), ] }}} which can be resolved the following ways: {{{#!python >>> reverse('admin:index', current_app='admin1') '/admin1/' >>> reverse('admin:index', current_app='admin2') '/admin2/' >>> reverse('admin1:index') '/admin1/' }}} As can be seen in the examples above, the part before the colon can either act as instance or application name, depending on what was passed in as described by: https://docs.djangoproject.com/en/1.7/topics/http/urls/#reversing-namespaced-urls To avoid ambiguity in resolving URLs, the `current_app` approach should be preferred. Templates don't have the luxury of specifying `current_app` via the `url`-tag but can set it on the `Context` (or `request` since 1.8). This makes it hard for application developers to provide a list of links to all admin pages (url reversal has to be done in the view) and in general puts `current_app` into places where it should not be. == Suggested improvements == Provide a way to explicitly pass `current_app` to the URL tag like for `reverse`, this could be done as follows: {{{ {% url 'admin:index' arg1 arg2 current_app='admin1' %} }}} or {{{ {% url 'admin:index' on|in 'admin1' arg1 arg2 %} }}} Both of them are technically speaking backwards incompatible but could be done via an url tag from the future library. While passing `current_app` to the url tag is a nice and needed feature, it should also be noted that a way to obtain the current app implicitly like currently would be nice to have to avoid passing in the current app on every call. Currently this is done via setting `current_app` on `Context|request`. To remove this special casing, the url tag should just lookup the key `current_app` **in** the template context (and not on the `Context` object itself). This would again be backwards incompatible, but a worthwile change. One of the usecases for URL namespaces is to prevent name collisions, which is usually done as follows: {{{#!python blog_patterns = [ url(…) ] urlpatterns = [ url('^blog/', include(blog_patterns, namespace='blog', app_name='blog'), ] }}} It should be noted that in this case there is technically no benefit over using url names like 'blog_index', but using namespaces from the start allows an easier change later on. Reversing can be done without providing `current_app` as the default app will get picked anyways. This is, while not an intended usage, a nice feature and should stay.