mirror of
https://github.com/Hopiu/wagtail.git
synced 2026-04-12 11:00:59 +00:00
134 lines
5.2 KiB
ReStructuredText
134 lines
5.2 KiB
ReStructuredText
.. _modeladmin_reversing_urls:
|
|
|
|
=========================
|
|
Reversing ModelAdmin URLs
|
|
=========================
|
|
|
|
It's sometimes useful to be able to derive the ``index`` (listing) or
|
|
``create`` URLs for a model along with the ``edit``, ``delete`` or
|
|
``inspect`` URL for a specific object in a model you have registered via
|
|
the ``modeladmin`` app.
|
|
|
|
Wagtail itself does this by instantiating each ``ModelAdmin`` class you have
|
|
registered, and using the ``url_helper`` attribute of each instance to
|
|
determine what these URLs are.
|
|
|
|
You can take a similar approach in your own code too, by creating a
|
|
``ModelAdmin`` instance yourself, and using its ``url_helper``
|
|
to determine URLs.
|
|
|
|
See below for some examples:
|
|
|
|
.. contents::
|
|
:local:
|
|
:depth: 1
|
|
|
|
-------------------------------------------------------------------
|
|
Getting the ``edit`` or ``delete`` or ``inspect`` URL for an object
|
|
-------------------------------------------------------------------
|
|
|
|
In this example, we will provide a quick way to ``edit`` the Author that is
|
|
linked to a blog post from the admin page listing menu. We have defined
|
|
an ``AuthorModelAdmin`` class and registered it with Wagtail to allow
|
|
``Author`` objects to be administered via the admin area. The ``BlogPage``
|
|
model has an ``author`` field (a ``ForeignKey`` to the ``Author`` model)
|
|
to allow a single author to be specified for each post.
|
|
|
|
.. code-block:: python
|
|
|
|
# file: wagtail_hooks.py
|
|
|
|
from wagtail.admin.widgets import PageListingButton
|
|
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
|
|
from wagtail.core import hooks
|
|
|
|
# Author & BlogPage model not shown in this example
|
|
from models import Author
|
|
|
|
# ensure our modeladmin is created
|
|
class AuthorModelAdmin(ModelAdmin):
|
|
model = Author
|
|
menu_order = 200
|
|
|
|
# Creating an instance of `AuthorModelAdmin`
|
|
author_modeladmin = AuthorModelAdmin()
|
|
|
|
@hooks.register('register_page_listing_buttons')
|
|
def add_author_edit_buttons(page, page_perms, is_parent=False):
|
|
"""
|
|
For pages that have an author, add an additional button to the page listing,
|
|
linking to the 'edit' page for that author.
|
|
"""
|
|
author_id = getattr(page, 'author_id', None)
|
|
if author_id:
|
|
# the url helper will return something like: /admin/my-app/author/edit/2/
|
|
author_edit_url = author_modeladmin.url_helper.get_action_url('edit', author_id)
|
|
yield PageListingButton('Edit Author', author_edit_url, priority=10)
|
|
|
|
modeladmin_register(AuthorModelAdmin)
|
|
|
|
|
|
As you can see from the example above, when using ``get_action_url()`` to
|
|
generate object-specific URLs, the target object's primary key value must be supplied
|
|
so that it can be included in the resulting URL (e.g. ``"/admin/my-app/author/edit/2/"``).
|
|
The following object-specific action names are supported by ``get_action_url()``:
|
|
|
|
``'edit'``
|
|
Returns a URL for updating a specific object.
|
|
|
|
``'delete'``
|
|
Returns a URL for deleting a specific object.
|
|
|
|
``'inspect'``
|
|
Returns a URL for viewing details of a specific object.
|
|
**NOTE:** This will only work if ``inspect_view_enabled`` is set to
|
|
``True`` on your ``ModelAdmin`` class.
|
|
|
|
|
|
.. note::
|
|
If you are using string values as primary keys for you model, you may need to handle
|
|
cases where the key contains characters that are not URL safe. Only alphanumerics
|
|
(``[0-9a-zA-Z]``), or the following special characters are safe:
|
|
``$``, ``-``, ``_``, ``.``, ``+``, ``!``, ``*``, ``'``, ``(``, ``)``.
|
|
|
|
``django.contrib.admin.utils.quote()`` can be used to safely encode these primary
|
|
key values before passing them to ``get_action_url()``. Failure to do this may result
|
|
in Wagtail not being able to recognise the primary key when the URL is visited,
|
|
resulting in 404 errors.
|
|
|
|
|
|
---------------------------------------------------
|
|
Getting the ``index`` or ``create`` URL for a model
|
|
---------------------------------------------------
|
|
|
|
There are URLs available for the model listing view (action is ``'index'``) and
|
|
the create model view (action is ``'create'``). Each of these has an equivalent
|
|
shortcut available; ``url_helper.index_url`` and ``url_helper.create_url``.
|
|
|
|
For example:
|
|
|
|
.. code-block:: python
|
|
|
|
from .wagtail_hooks import AuthorModelAdmin
|
|
|
|
url_helper = AuthorModelAdmin().url_helper
|
|
|
|
index_url = url_helper.get_action_url('index')
|
|
# OR we can use the 'index_url' shortcut
|
|
also_index_url = url_helper.index_url # note: do not call this property as a function
|
|
# both will output /admin/my-app/author
|
|
|
|
create_url = url_helper.get_action_url('create')
|
|
# OR we can use the 'create_url' shortcut
|
|
also_create_url = url_helper.create_url # note: do not call this property as a function
|
|
# both will output /admin/my-app/author/create
|
|
|
|
.. note::
|
|
|
|
If you have registered a page type with ``modeladmin`` (e.g. ``BlogPage``), and pages
|
|
of that type can be added to more than one place in the page tree, when a user visits
|
|
the `create` URL, they'll be automatically redirected to another view to choose a
|
|
parent for the new page. So, this isn't something you need to check or cater for in
|
|
your own code.
|
|
|
|
To customise ``url_helper`` behaviour, see :ref:`modeladmin_url_helper_class`.
|