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:
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.
# file: wagtail_hooks.py
from wagtail.admin.widgets import PageListingButton
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
from wagtail 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, user, next_url=None):
"""
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 (for example "/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 toTrue
on yourModelAdmin
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:
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
(for example 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 ModelAdmin.url_helper_class.