Changes between Initial Version and Version 1 of URLNamespacing


Ignore:
Timestamp:
Jan 4, 2015, 12:14:57 PM (10 years ago)
Author:
Florian Apolloner
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • URLNamespacing

    v1 v1  
     1= URLNamespacing =
     2
     3== Usecases ==
     4
     5The 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…
     6
     7 * Multiple deployments of a single App (like the admin)
     8 *  Prevention of name clashes between view names (This was original not intended)
     9
     10== Analysis of URL namespaces ==
     11
     12URL 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':
     13
     14{{{#!python
     15urlpatterns = [
     16  url('^admin1/', include(admin_urls, 'admin1', 'admin'),
     17  url('^admin2/', include(admin_urls, 'admin2', 'admin'),
     18]
     19}}}
     20
     21which can be resolved the following ways:
     22
     23{{{#!python
     24>>> reverse('admin:index', current_app='admin1')
     25'/admin1/'
     26>>> reverse('admin:index', current_app='admin2')
     27'/admin2/'
     28>>> reverse('admin1:index')
     29'/admin1/'
     30}}}
     31
     32As 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
     33
     34To avoid ambiguity in resolving URLs, the `current_app` approach should be preferred.
     35
     36Templates 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.
     37
     38== Suggested improvements ==   
     39
     40Provide a way to explicitly pass `current_app` to the URL tag like for `reverse`, this could be done as follows:
     41{{{
     42 {% url 'admin:index' arg1 arg2 current_app='admin1' %}
     43}}}
     44or
     45{{{
     46 {% url 'admin:index' on|in 'admin1' arg1 arg2 %}
     47}}}
     48Both 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.
     49
     50One of the usecases for URL namespaces is to prevent name collisions, which is usually done as follows:
     51
     52{{{#!python
     53blog_patterns = [
     54  url(…)
     55]
     56
     57urlpatterns = [
     58  url('^blog/', include(blog_patterns, 'blog', 'blog'),
     59]
     60}}}
     61
     62It 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.
Back to Top