6.6 KiB
(wagtailsnippets_custom_admin_views)=
Customising admin views for snippets
Additional customisations to the admin views for each snippet model can be achieved through a custom {class}~SnippetViewSet
class. The SnippetViewSet
is a subclass of {class}.ModelViewSet
, with snippets-specific properties provided by default. Hence, it supports the same customisations provided by ModelViewSet
such as customising the listing view (e.g. adding custom columns, filters), creating a custom menu item, and more.
Before proceeding, ensure that you register the snippet model using register_snippet
as a function instead of a decorator, as described in .
For demonstration, consider the following Member
model and a MemberFilterSet
class:
# models.py
from django.db import models
from wagtail.admin.filters import WagtailFilterSet
class Member(models.Model):
class ShirtSize(models.TextChoices):
SMALL = "S", "Small"
MEDIUM = "M", "Medium"
LARGE = "L", "Large"
EXTRA_LARGE = "XL", "Extra Large"
name = models.CharField(max_length=255)
shirt_size = models.CharField(max_length=5, choices=ShirtSize.choices, default=ShirtSize.MEDIUM)
def get_shirt_size_display(self):
return self.ShirtSize(self.shirt_size).label
get_shirt_size_display.admin_order_field = "shirt_size"
get_shirt_size_display.short_description = "Size description"
class MemberFilterSet(WagtailFilterSet):
class Meta:
model = Member
fields = ["shirt_size"]
And the following is the snippet's corresponding SnippetViewSet
subclass:
from wagtail.admin.panels import FieldPanel
from wagtail.admin.ui.tables import UpdatedAtColumn
from wagtail.snippets.models import register_snippet
from wagtail.snippets.views.snippets import SnippetViewSet
from myapp.models import Member, MemberFilterSet
class MemberViewSet(SnippetViewSet):
model = Member
icon = "user"
list_display = ["name", "shirt_size", "get_shirt_size_display", UpdatedAtColumn()]
list_per_page = 50
inspect_view_enabled = True
admin_url_namespace = "member_views"
base_url_path = "internal/member"
filterset_class = MemberFilterSet
# alternatively, you can use the following instead of filterset_class
# list_filter = ["shirt_size"]
# or
# list_filter = {"shirt_size": ["exact"], "name": ["icontains"]}
edit_handler = TabbedInterface([
ObjectList([FieldPanel("name")], heading="Details"),
ObjectList([FieldPanel("shirt_size")], heading="Preferences"),
])
register_snippet(MemberViewSet)
(wagtailsnippets_icon)=
Icon
You can define an {attr}~.ViewSet.icon
attribute on the SnippetViewSet
to specify the icon that is used across the admin for this snippet type. The icon
needs to be registered in the Wagtail icon library. If icon
is not set, the default "snippet"
icon is used.
URL namespace and base URL path
The {attr}~.ViewSet.url_namespace
property can be overridden to use a custom URL namespace for the URL patterns of the views. If unset, it defaults to wagtailsnippets_{app_label}_{model_name}
. Meanwhile, overriding {attr}~.ViewSet.url_prefix
allows you to customise the base URL path relative to the Wagtail admin URL. If unset, it defaults to snippets/app_label/model_name
.
Similar URL customisations are also possible for the snippet chooser views through {attr}~SnippetViewSet.chooser_admin_url_namespace
, {attr}~SnippetViewSet.chooser_base_url_path
, {meth}~SnippetViewSet.get_chooser_admin_url_namespace
, and {meth}~SnippetViewSet.get_chooser_admin_base_path
.
Listing view
You can customise the listing view to add custom columns, filters, pagination, etc. via various attributes available on the SnippetViewSet
. Refer to the listing view customisations for ModelViewSet
for more details.
Additionally, you can customise the base queryset for the listing view by overriding the {meth}~SnippetViewSet.get_queryset
method.
Inspect view
The inspect view is disabled by default, as it's not often useful for most models. To enable it, set {attr}~.ModelViewSet.inspect_view_enabled
to True
. Refer to the inspect view customisations for ModelViewSet
for more details.
(wagtailsnippets_templates)=
Templates
Template customisations work the same way as for ModelViewSet
, except that the {attr}~.ModelViewSet.template_prefix
defaults to wagtailsnippets/snippets/
. Refer to the template customisations for ModelViewSet
for more details.
Menu item
By default, registering a snippet model will add a "Snippets" menu item to the sidebar menu. However, you can configure a snippet model to have its own top-level menu item in the sidebar menu by setting {attr}~.ViewSet.add_to_admin_menu
to True
. Refer to the menu customisations for ModelViewSet
for more details.
An example of a custom SnippetViewSet
subclass with add_to_admin_menu
set to True
:
from wagtail.snippets.views.snippets import SnippetViewSet
class AdvertViewSet(SnippetViewSet):
model = Advert
icon = "crosshairs"
menu_label = "Advertisements"
menu_name = "adverts"
menu_order = 300
add_to_admin_menu = True
Multiple snippet models can also be grouped under a single menu item using a {attr}~SnippetViewSetGroup
. You can do this by setting the {attr}~SnippetViewSet.model
attribute on the SnippetViewSet
classes and then registering the SnippetViewSetGroup
subclass instead of each individual model or viewset:
from wagtail.snippets.views.snippets import SnippetViewSet, SnippetViewSetGroup
class AdvertViewSet(SnippetViewSet):
model = Advert
icon = "crosshairs"
menu_label = "Advertisements"
menu_name = "adverts"
class ProductViewSet(SnippetViewSet):
model = Product
icon = "desktop"
menu_label = "Products"
menu_name = "banners"
class MarketingViewSetGroup(SnippetViewSetGroup):
items = (AdvertViewSet, ProductViewSet)
menu_icon = "folder-inverse"
menu_label = "Marketing"
menu_name = "marketing"
# When using a SnippetViewSetGroup class to group several SnippetViewSet classes together,
# only register the SnippetViewSetGroup class. You do not need to register each snippet
# model or viewset separately.
register_snippet(MarketingViewSetGroup)
If all snippet models have their own menu items, the "Snippets" menu item will not be shown.
Various additional attributes are available to customise the viewset - see {class}~SnippetViewSet
.