Fixed #10061 -- Added namespacing for named URLs - most importantly, for the admin site, where the absence of this facility was causing problems. Thanks to the many people who contributed to and helped review this patch.

This change is backwards incompatible for anyone that is using the named URLs
introduced in [9739]. Any usage of the old admin_XXX names need to be modified
to use the new namespaced format; in many cases this will be as simple as a
search & replace for "admin_" -> "admin:". See the docs for more details on
the new URL names, and the namespace resolution strategy.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@11250 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2009-07-16 16:16:13 +00:00
parent 9fd19c0161
commit 8d48eaa064
20 changed files with 544 additions and 119 deletions

View file

@ -1242,7 +1242,7 @@ or :attr:`AdminSite.login_template` properties.
``AdminSite`` objects
=====================
.. class:: AdminSite
.. class:: AdminSite(name=None)
A Django administrative site is represented by an instance of
``django.contrib.admin.sites.AdminSite``; by default, an instance of
@ -1256,6 +1256,14 @@ or add anything you like. Then, simply create an instance of your
Python class), and register your models and ``ModelAdmin`` subclasses
with it instead of using the default.
.. versionadded:: 1.1
When constructing an instance of an ``AdminSite``, you are able to provide
a unique instance name using the ``name`` argument to the constructor. This
instance name is used to identify the instance, especially when
:ref:`reversing admin URLs <admin-reverse-urls>`. If no instance name is
provided, a default instance name of ``admin`` will be used.
``AdminSite`` attributes
------------------------
@ -1353,10 +1361,10 @@ a pattern for your new view.
.. note::
Any view you render that uses the admin templates, or extends the base
admin template, should include in it's context a variable named
``admin_site`` that contains the name of the :class:`AdminSite` instance. For
:class:`AdminSite` instances, this means ``self.name``; for :class:`ModelAdmin`
instances, this means ``self.admin_site.name``.
admin template, should provide the ``current_app`` argument to
``RequestContext`` or ``Context`` when rendering the template. It should
be set to either ``self.name`` if your view is on an ``AdminSite`` or
``self.admin_site.name`` if your view is on a ``ModelAdmin``.
.. _admin-reverse-urls:
@ -1370,37 +1378,31 @@ accessible using Django's :ref:`URL reversing system <naming-url-patterns>`.
The :class:`AdminSite` provides the following named URL patterns:
====================== =============================== =============
Page URL name Parameters
====================== =============================== =============
Index ``admin_index``
Logout ``admin_logout``
Password change ``admin_password_change``
Password change done ``admin_password_change_done``
i18n javascript ``admin_jsi18n``
Application index page ``admin_app_list`` ``app_label``
====================== =============================== =============
These names will be prefixed with the name of the :class:`AdminSite` instance,
plus an underscore. For example, if your :class:`AdminSite` was named
``custom``, then the Logout view would be served using a URL with the name
``custom_admin_logout``. The default :class:`AdminSite` doesn't use a prefix
in it's URL names.
====================== ======================== =============
Page URL name Parameters
====================== ======================== =============
Index ``index``
Logout ``logout``
Password change ``password_change``
Password change done ``password_change_done``
i18n javascript ``jsi18n``
Application index page ``app_list`` ``app_label``
====================== ======================== =============
Each :class:`ModelAdmin` instance provides an additional set of named URLs:
====================== ===================================================== =============
Page URL name Parameters
====================== ===================================================== =============
Changelist ``admin_{{ app_label }}_{{ model_name }}_changelist``
Add ``admin_{{ app_label }}_{{ model_name }}_add``
History ``admin_{{ app_label }}_{{ model_name }}_history`` ``object_id``
Delete ``admin_{{ app_label }}_{{ model_name }}_delete`` ``object_id``
Change ``admin_{{ app_label }}_{{ model_name }}_change`` ``object_id``
====================== ===================================================== =============
====================== =============================================== =============
Page URL name Parameters
====================== =============================================== =============
Changelist ``{{ app_label }}_{{ model_name }}_changelist``
Add ``{{ app_label }}_{{ model_name }}_add``
History ``{{ app_label }}_{{ model_name }}_history`` ``object_id``
Delete ``{{ app_label }}_{{ model_name }}_delete`` ``object_id``
Change ``{{ app_label }}_{{ model_name }}_change`` ``object_id``
====================== =============================================== =============
Again, these names will be prefixed by the name of the :class:`AdminSite` in
which they are deployed.
These named URLs are registered with the application namespace ``admin``, and
with an instance namespace corresponding to the name of the Site instance.
So - if you wanted to get a reference to the Change view for a particular
``Choice`` object (from the polls application) in the default admin, you would
@ -1408,8 +1410,16 @@ call::
>>> from django.core import urlresolvers
>>> c = Choice.objects.get(...)
>>> change_url = urlresolvers.reverse('admin_polls_choice_change', args=(c.id,))
>>> change_url = urlresolvers.reverse('admin:polls_choice_change', args=(c.id,))
However, if the admin instance was named ``custom``, you would need to call::
This will find the first registered instance of the admin application (whatever the instance
name), and resolve to the view for changing ``poll.Choice`` instances in that instance.
>>> change_url = urlresolvers.reverse('custom_admin_polls_choice_change', args=(c.id,))
If you want to find a URL in a specific admin instance, provide the name of that instance
as a ``current_app`` hint to the reverse call. For example, if you specifically wanted
the admin view from the admin instance named ``custom``, you would need to call::
>>> change_url = urlresolvers.reverse('custom:polls_choice_change', args=(c.id,))
For more details, see the documentation on :ref:`reversing namespaced URLs
<topics-http-reversing-url-namespaces>`.

View file

@ -86,9 +86,16 @@ Rendering a context
Once you have a compiled ``Template`` object, you can render a context -- or
multiple contexts -- with it. The ``Context`` class lives at
``django.template.Context``, and the constructor takes one (optional)
argument: a dictionary mapping variable names to variable values. Call the
``Template`` object's ``render()`` method with the context to "fill" the
``django.template.Context``, and the constructor takes two (optional)
arguments:
* A dictionary mapping variable names to variable values.
* The name of the current application. This application name is used
to help :ref:`resolve namespaced URLs<topics-http-reversing-url-namespaces>`.
If you're not using namespaced URLs, you can ignore this argument.
Call the ``Template`` object's ``render()`` method with the context to "fill" the
template::
>>> from django.template import Context, Template
@ -549,13 +556,13 @@ Here are the template loaders that come with Django:
Note that the loader performs an optimization when it is first imported: It
caches a list of which :setting:`INSTALLED_APPS` packages have a
``templates`` subdirectory.
This loader is enabled by default.
``django.template.loaders.eggs.load_template_source``
Just like ``app_directories`` above, but it loads templates from Python
eggs rather than from the filesystem.
This loader is disabled by default.
Django uses the template loaders in order according to the

View file

@ -795,6 +795,16 @@ missing. In practice you'll use this to link to views that are optional::
<a href="{{ the_url }}">Link to optional stuff</a>
{% endif %}
.. versionadded:: 1.1
If you'd like to retrieve a namespaced URL, specify the fully qualified name::
{% url myapp:view-name %}
This will follow the normal :ref:`namespaced URL resolution strategy
<topics-http-reversing-url-namespaces>`, including using any hints provided
by the context as to the current application.
.. templatetag:: widthratio
widthratio