===================== ``ModelAdmin`` ===================== The ``modeladmin`` module allows you to add any model in your project to the Wagtail admin. You can create customisable listing pages for a model, including plain Django models, and add navigation elements so that a model can be accessed directly from the Wagtail admin. Simply extend the ``ModelAdmin`` class, override a few attributes to suit your needs, register it with Wagtail using an easy one-line ``modeladmin_register`` method (you can copy and paste from the examples below), and you're good to go. Your model doesn’t need to extend ``Page`` or be registered as a ``Snippet``, and it won’t interfere with any of the existing admin functionality that Wagtail provides. .. _modeladmin_feature_summary: ------------------- Summary of features ------------------- - A customisable list view, allowing you to control what values are displayed for each row, available options for result filtering, default ordering, spreadsheet downloads and more. - Access your list views from the Wagtail admin menu easily with automatically generated menu items, with automatic 'active item' highlighting. Control the label text and icons used with easy-to-change attributes on your class. - An additional ``ModelAdminGroup`` class, that allows you to group your related models, and list them together in their own submenu, for a more logical user experience. - Simple, robust **add** and **edit** views for your non-Page models that use the panel configurations defined on your model using Wagtail's edit panels. - For Page models, the system directs to Wagtail's existing add and edit views, and returns you back to the correct list page, for a seamless experience. - Full respect for permissions assigned to your Wagtail users and groups. Users will only be able to do what you want them to! - All you need to easily hook your ``ModelAdmin`` classes into Wagtail, taking care of URL registration, menu changes, and registering any missing model permissions, so that you can assign them to Groups. - **Built to be customisable** - While ``modeladmin`` provides a solid experience out of the box, you can easily use your own templates, and the ``ModelAdmin`` class has a large number of methods that you can override or extend, allowing you to customise the behaviour to a greater degree. --------------------------------------------------- Want to know more about customising ``ModelAdmin``? --------------------------------------------------- .. toctree:: :maxdepth: 1 primer menu_item indexview create_edit_delete_views inspectview chooseparentview tips_and_tricks/index .. _modeladmin_usage: Installation ------------ Add ``wagtail.contrib.modeladmin`` to your ``INSTALLED_APPS``: .. code-block:: python INSTALLED_APPS = [ ... 'wagtail.contrib.modeladmin', ] How to use ---------- .. _modeladmin_example_simple: A simple example ^^^^^^^^^^^^^^^^ Let's say your website is for a local library. They have a model called ``Book`` that appears across the site in many places. You can define a normal Django model for it, then use ModelAdmin to create a menu in Wagtail's admin to create, view, and edit ``Book`` entries. ``models.py`` looks like this: .. code-block:: python from django.db import models from wagtail.admin.edit_handlers import FieldPanel from wagtail.images.edit_handlers import ImageChooserPanel class Book(models.Model): title = models.CharField(max_length=255) author = models.CharField(max_length=255) cover_photo = models.ForeignKey( 'wagtailimages.Image', null=True, blank=True, on_delete=models.SET_NULL, related_name='+' ) panels = [ FieldPanel('title'), FieldPanel('author'), ImageChooserPanel('cover_photo') ] .. tip:: You can specify ``FieldPanels`` like ``ImageChooserPanel``, ``PageChooserPanel``, and ``DocumentChooserPanel`` within the ``panels`` attribute of the model. This lets you use Wagtail-specific features in an otherwise traditional Django model. ``wagtail_hooks.py`` in your app directory would look something like this: .. code-block:: python from wagtail.contrib.modeladmin.options import ( ModelAdmin, modeladmin_register) from .models import Book class BookAdmin(ModelAdmin): model = Book menu_label = 'Book' # ditch this to use verbose_name_plural from model menu_icon = 'pilcrow' # change as required menu_order = 200 # will put in 3rd place (000 being 1st, 100 2nd) add_to_settings_menu = False # or True to add your model to the Settings sub-menu exclude_from_explorer = False # or True to exclude pages of this type from Wagtail's explorer view list_display = ('title', 'author') list_filter = ('author',) search_fields = ('title', 'author') # Now you just need to register your customised ModelAdmin class with Wagtail modeladmin_register(BookAdmin) .. _modeladmin_example_complex: A more complicated example ^^^^^^^^^^^^^^^^^^^^^^^^^^ In addition to ``Book``, perhaps we also want to add ``Author`` and ``Genre`` models to our app and display a menu item for each of them, too. Creating lots of menus can add up quickly, so it might be a good idea to group related menus together. This section show you how to create one menu called *Library* which expands to show submenus for *Book*, *Author*, and *Genre*. Assume we've defined ``Book``, ``Author``, and ``Genre`` models in ``models.py``. ``wagtail_hooks.py`` in your app directory would look something like this: .. code-block:: python from wagtail.contrib.modeladmin.options import ( ModelAdmin, ModelAdminGroup, modeladmin_register) from .models import ( Book, Author, Genre) class BookAdmin(ModelAdmin): model = Book menu_label = 'Book' # ditch this to use verbose_name_plural from model menu_icon = 'pilcrow' # change as required list_display = ('title', 'author') list_filter = ('genre', 'author') search_fields = ('title', 'author') class AuthorAdmin(ModelAdmin): model = Author menu_label = 'Author' # ditch this to use verbose_name_plural from model menu_icon = 'user' # change as required list_display = ('first_name', 'last_name') list_filter = ('first_name', 'last_name') search_fields = ('first_name', 'last_name') class GenreAdmin(ModelAdmin): model = Genre menu_label = 'Genre' # ditch this to use verbose_name_plural from model menu_icon = 'group' # change as required list_display = ('name',) list_filter = ('name',) search_fields = ('name',) class LibraryGroup(ModelAdminGroup): menu_label = 'Library' menu_icon = 'folder-open-inverse' # change as required menu_order = 200 # will put in 3rd place (000 being 1st, 100 2nd) items = (BookAdmin, AuthorAdmin, GenreAdmin) # When using a ModelAdminGroup class to group several ModelAdmin classes together, # you only need to register the ModelAdminGroup class with Wagtail: modeladmin_register(LibraryGroup) .. _modeladmin_multi_registration: Registering multiple classes in one ``wagtail_hooks.py`` file ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Each time you call ``modeladmin_register(MyAdmin)`` it creates a new top-level menu item in Wagtail's left sidebar. You can call this multiple times within the same ``wagtail_hooks.py`` file if you want. The example below will create 3 top-level menus. .. code-block:: python class BookAdmin(ModelAdmin): model = Book ... class MovieAdmin(ModelAdmin): model = MovieModel ... class MusicAdminGroup(ModelAdminGroup): menu_label = _("Music") items = (AlbumAdmin, ArtistAdmin) ... modeladmin_register(BookAdmin) modeladmin_register(MovieAdmin) modeladmin_register(MusicAdminGroup)