From fc21729a243e7ac76ac00b680f9a256c0bacc776 Mon Sep 17 00:00:00 2001 From: LB Johnston Date: Wed, 30 Jan 2019 19:30:15 +1000 Subject: [PATCH] add docs with instructions on how to generate urls for modeladmin --- CHANGELOG.txt | 1 + docs/reference/contrib/modeladmin/index.rst | 9 +- docs/reference/contrib/modeladmin/primer.rst | 2 + .../contrib/modeladmin/reversing_urls.rst | 134 ++++++++++++++++++ docs/releases/2.5.rst | 1 + 5 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 docs/reference/contrib/modeladmin/reversing_urls.rst diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 85554a9a5..2dd1a3318 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -17,6 +17,7 @@ Changelog * `edit_handler` and `panels` can now be defined on a `ModelAdmin` definition (Thomas Kremmel) * Add Learn Wagtail to third-party tutorials in documentation (Matt Westcott) * Add a Django setting `TAG_LIMIT` to limit number of tags that can be added to any taggit model (Mani) + * Added instructions on how to generate urls for `ModelAdmin` to documentation (LB (Ben Johnston), Andy Babic) * Fix: Set `SERVER_PORT` to 443 in `Page.dummy_request()` for HTTPS sites (Sergey Fedoseev) * Fix: Include port number in `Host` header of `Page.dummy_request()` (Sergey Fedoseev) * Fix: Validation error messages in `InlinePanel` no longer count towards `max_num` when disabling the 'add' button (Todd Dembrey, Thibaud Colas) diff --git a/docs/reference/contrib/modeladmin/index.rst b/docs/reference/contrib/modeladmin/index.rst index 2e63508a6..519c3541c 100644 --- a/docs/reference/contrib/modeladmin/index.rst +++ b/docs/reference/contrib/modeladmin/index.rst @@ -194,7 +194,7 @@ Assume we've defined ``Book``, ``Author``, and ``Genre`` models in modeladmin_register(LibraryGroup) -.. _modeladmin_multi_registeration: +.. _modeladmin_multi_registration: Registering multiple classes in one ``wagtail_hooks.py`` file ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -222,3 +222,10 @@ the same ``wagtail_hooks.py`` file if you want. The example below will create modeladmin_register(BookAdmin) modeladmin_register(MovieAdmin) modeladmin_register(MusicAdminGroup) + + +------------------------- +Additional Tips & Tricks +------------------------- + +* To programatically generate URLs for any of your ``ModelAdmin`` views, see :ref:`modeladmin_reversing_urls`. diff --git a/docs/reference/contrib/modeladmin/primer.rst b/docs/reference/contrib/modeladmin/primer.rst index 4f1d624ff..7512050c9 100644 --- a/docs/reference/contrib/modeladmin/primer.rst +++ b/docs/reference/contrib/modeladmin/primer.rst @@ -216,6 +216,8 @@ will support that too. However, it's highly recommended that you use integrating with your ``ModelAdmin`` class much easier and will provide a bunch of useful attributes and methods to get you started. +You can also use the url_helper to easily reverse URLs for any ModelAdmin see :ref:`modeladmin_reversing_urls`. + .. _modeladmin_overriding_helper_classes: ------------------------- diff --git a/docs/reference/contrib/modeladmin/reversing_urls.rst b/docs/reference/contrib/modeladmin/reversing_urls.rst new file mode 100644 index 000000000..ec403f942 --- /dev/null +++ b/docs/reference/contrib/modeladmin/reversing_urls.rst @@ -0,0 +1,134 @@ +.. _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`. diff --git a/docs/releases/2.5.rst b/docs/releases/2.5.rst index 89b37fdee..219481585 100644 --- a/docs/releases/2.5.rst +++ b/docs/releases/2.5.rst @@ -27,6 +27,7 @@ Other features * ``edit_handler`` and ``panels`` can now be defined on a ``ModelAdmin`` definition (Thomas Kremmel) * Add Learn Wagtail to third-party tutorials in documentation (Matt Westcott) * Add a Django setting ``TAG_LIMIT`` to limit number of tags that can be added to any taggit model (Mani) + * Added instructions on how to generate urls for ``ModelAdmin`` to documentation (LB (Ben Johnston), Andy Babic) Bug fixes