可以通过自定义 SnippetViewSet 类自定义每个片段模型的管理视图。SnippetViewSetModelViewSet 的子类,默认情况下提供特定于片段的属性。因此,它支持与 ModelViewSet 提供的相同的自定义,例如自定义列表视图(例如,添加自定义列、过滤器)、创建自定义菜单项等等。

在继续之前,请确保使用 register_snippet 作为函数而不是装饰符来注册片段模型,如注册片段中所述。

为了演示,考虑下面的 Member 模型和 MemberFilterSet 类:

# 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"]

下面是片段对应的 SnippetViewSet 子类:

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)

图标

您可以在 SnippetViewSet 上定义一个图标属性,以指定用于此片段类型的跨管理的图标。该 icon 需要在 Wagtail 图标库中注册。如果未设置 icon,则使用默认的“snippet”图标。

URL 命名空间和基 URL 路径

url_namespace 属性可以被重写,以便为视图的 URL 模式使用自定义 URL 命名空间。如果未设置,则默认为 wagtailsnippets_{app_label}_{model_name} 。同时,重写 url_prefix 允许你自定义相对于 Wagtail 管理 URL 的基 URL 路径。如果未设置,则默认为 snippets/app_label/model_name

对于片段选择器视图,也可以通过 chooser_admin_url_namespace、chooser_base_url_path、get_chooser_admin_url_namespace() 和 get_chooser_admin_base_path() 进行类似的URL定制。

列表视图

您可以自定义列表视图,使用 SnippetViewSet 提供的各种属性添加自定义列、过滤器、分页等。有关更多细节,请参考为 ModelViewSet 定制列表视图。

此外,您可以通过覆盖 get_queryset() 方法来定制列表视图的基本查询集。

5.1新版功能:
添加了导出列表视图的功能。

检查视图 (inspect view)

5.1新版功能 :添加了启用检查视图的功能。

检查视图在默认情况下是禁用的,因为它对大多数模型并不常用。要启用它,请将 inspect_view_enabled 设置为 True 。有关更多细节,请参考为 ModelViewSet 定制检查视图。

模板

模板定制的工作方式与 ModelViewSet 相同,除了 template_prefix 默认为 wagtailsnippets/snippets/ 。更多细节请参考为 ModelViewSet 定制模板。

默认情况下,注册一个片段模型将会在侧边栏菜单中添加一个“片段”菜单项。但是,您可以通过将 add_to_admin_menu 设置为 True 来配置片段模型,使其在侧边栏菜单中拥有自己的顶级菜单项。更多细节请参考为 ModelViewSet 定制菜单。

一个自定义 SnippetViewSet 子类的例子,add_to_admin_menu 设置为 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

还可以使用 SnippetViewSetGroup 将多个片段模型分组到单个菜单项下。你可以在 SnippetViewSet 类上设置 model 属性,然后注册 SnippetViewSetGroup 子类而不是注册每个单独的模型或视图集:

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)

如果所有片段模型都有自己的菜单项,“片段”菜单项将不会显示。

各种附加属性可用于自定义视图集 - 参见 SnippetViewSet。