Wagtail 5.2 LTS 版本全解析:图片性能优化、OpenSearch 支持、ModelViewSet 增强与升级指南
2026/9/14 9:46:06 网站建设 项目流程

Wagtail 5.2 LTS 版本全解析:图片性能优化、OpenSearch 支持、ModelViewSet 增强与升级指南

【免费下载链接】wagtailA Django content management system focused on flexibility and user experience项目地址: https://gitcode.com/GitHub_Trending/wa/wagtail

Wagtail 5.2 于 2023 年 11 月 1 日发布,并被正式指定为Long Term Support(LTS)长期支持版本——在下一个 LTS 版本到来之前(通常为期 12 个月),该系列会持续接收针对安全问题和数据丢失问题所需的维护更新。本篇文章以 Wagtail 5.2 官方发布说明 为主线,结合当前仓库源码,系统梳理 5.2 的核心新特性(重设计的页面列表、OpenSearch 支持、picture/srcset_image响应式图片标签、Stimulus 客户端扩展、ModelViewSet能力迁移)、逐条展开升级注意事项,并给出可落地的迁移示例。读完本文,你将掌握 5.2 的新能力用法、底层实现原理,以及从旧版本平滑升级所需的全部改动清单。

版本定位:LTS 与维护周期

Wagtail 5.2 被指定为 Long Term Support(LTS)版本。根据发布说明,LTS 版本会在下一个 LTS 版本发布之前(通常是 12 个月)持续收到针对安全问题和数据丢失问题的维护更新。对于追求稳定、不愿频繁大版本升级的生产项目,5.2 系列是值得长期驻留的版本基线。它同时也是首个正式支持Python 3.12的版本(由 Matt Westcott 贡献),对升级 Python 运行环境的项目有直接意义。

亮点一:重设计的页面列表视图(Page Explorer)

5.2 对后台的页面资源管理器(page explorer)列表视图做了重新设计,以提供更流畅的导航与搜索体验。从官方截图可以看到,新的列表在搜索时呈现"精简"(slimmed-down)的结果行,行内直接展示标题、状态、操作等核心信息,配合新的面包屑与下拉按钮交互,整体信息密度和操作效率都有明显提升。该特性由 Ben Enright、Matt Westcott、Thibaud Colas 与 Sage Abdullah 共同开发。

亮点二:OpenSearch 正式支持

5.2 起,OpenSearch 被正式支持为 Elasticsearch 的替代方案(由 Matt Westcott 开发)。仓库中的对应后端实现位于 wagtail/search/backends/opensearch2.py 与 wagtail/search/backends/opensearch3.py,分别对应 OpenSearch 2.x 与 3.x。

完整的配置细节见 OpenSearch 配置文档,核心要点如下:

  • 通过WAGTAILSEARCH_BACKENDS设置选择后端,可用的后端标识为wagtail.search.backends.opensearch2(OpenSearch 2.x)与wagtail.search.backends.opensearch3(OpenSearch 3.x)。
  • 前置依赖是 OpenSearch 服务本身,以及 pip 安装的opensearch-py包,且包的大版本必须与所连接的 OpenSearch 大版本一致:
pip install "opensearch-py>=2,<3" # 对应 OpenSearch 2.x pip install "opensearch-py>=3,<4" # 对应 OpenSearch 3.x
  • 一个典型的配置示例:
WAGTAILSEARCH_BACKENDS = { "default": { "BACKEND": "wagtail.search.backends.opensearch3", "URLS": ["http://localhost:9200"], "INDEX": "wagtail", "TIMEOUT": 5, "AUTO_UPDATE": True, "ATOMIC_REBUILD": True, } }
  • 若使用 OpenSearch 的 demo 配置,其 TLS 证书位于 OpenSearch 配置目录(通常为/usr/share/opensearch/config//etc/opensearch/),客户端证书与密钥分别名为kirk.pemkirk-key.pem,可据此配置带认证的URLS
  • OpenSearch 后端兼容Amazon OpenSearch Service,但需要通过requests-aws4auth包处理基于 IAM 的认证,再在WAGTAILSEARCH_BACKENDS中配置相应的认证参数。

亮点三:picture / srcset_image 响应式多格式图片

5.2 为图片模板标签引入两大新成员,目标是显著降低全站图片体积、缩短加载时间并减小环境碳足迹(该特性由 Paarth Agarwal 与 Thibaud Colas 在 Google Summer of Code 项目及 Green Web Foundation、Green Coding Berlin 合作中完成):

  • picture标签:一次性按多种格式 × 多种尺寸批量生成图片,输出 HTML<picture>标签;
  • srcset_image标签:一次性生成多种尺寸,输出带srcset属性的<img>标签。

例如一次生成 6 个变体(AVIF/WebP/JPEG 三种格式 × 400/800 两种宽度):

{% picture page.photo format-{avif,webp,jpeg} width-{400,800} sizes="80vw" %}

输出:

<picture> <source sizes="80vw" srcset="/media/images/pied-wagtail.width-400.avif 400w, /media/images/pied-wagtail.width-800.avif 800w" type="image/avif"> <source sizes="80vw" srcset="/media/images/pied-wagtail.width-400.webp 400w, /media/images/pied-wagtail.width-800.webp 800w" type="image/webp"> <img sizes="80vw" srcset="/media/images/pied-wagtail.width-400.jpg 400w, /media/images/pied-wagtail.width-800.jpg 800w" src="/media/images/pied-wagtail.width-400.jpg" alt="A pied Wagtail" width="400" height="300"> </picture>

源码级原理

从源码看,这套机制的核心是Filter类的花括号展开(brace expansion)Picture/ResponsiveImage对象的 HTML 渲染:

  • wagtail/images/models.py 中的Filter.expand_spec()会把形如width-{100,200}的规格展开为["width-100", "width-200"],多个花括号段之间取笛卡尔积,再以|组合成完整规格串;对应地,srcset_image/picture标签允许的规格字符集扩大到包含{},(见 jinja2tags.py 中基于Filter.pipe_expanding_spec_pattern的语法校验)。
  • ResponsiveImage(wagtail/images/models.py)通过get_width_srcset()生成url 400w, url 800w形式的宽度描述符;单张图片时不输出srcset,并以第一张 rendition 作为兜底<img>
  • Picture(wagtail/images/models.py)按source_format_order = [avif, webp, jpeg, png, gif]的优先级决定<source>的书写顺序与"兜底格式"(fallback format),浏览器会选取其支持的第一种格式;若只生成了一种格式,则退化为带srcset的普通<img>并包裹在<picture>中。
  • 格式与质量可通过设置项调节:源码 wagtail/images/models.py 显示 JPEG 质量默认 76(WAGTAILIMAGES_JPEG_QUALITY)、WebP 默认 80(WAGTAILIMAGES_WEBP_QUALITY)、AVIF 默认 61(WAGTAILIMAGES_AVIF_QUALITY),并支持format-{...}系列操作符与preserve-svg跳过 SVG 转换等细节。

更完整的用法(多格式、响应式尺寸、AVIF 支持、AbstractImage.get_renditions())见 图片主题文档;这两个新标签同样支持在 Jinja 模板中使用,对应 API 见 Jinja2 参考(WagtailImagesExtension在 wagtail/images/jinja2tags.py 中把imageimage_urlsrcset_imagepicture注册为 Jinja 全局函数)。

亮点四:官方支持 Stimulus 客户端扩展

5.2 起,Wagtail 正式支持使用Stimulus进行后台(admin)客户端定制,并新增了专门的开发者文档页 扩展客户端侧(由核心贡献者 LB (Ben) Johnston 编写)。该文档覆盖客户端可扩展性的基础主题:

  • 添加自定义 JavaScript;
  • 基于 DOM 事件以及 Wagtail 自定义 DOM 事件进行扩展;
  • 基于 Stimulus 扩展;
  • 基于 React 扩展。

与之配套,5.2 同步将多个既有组件迁移到 Stimulus:表单提交列表的复选框切换迁移到共享的w-bulk控制器、编辑器未保存消息弹窗由共享的w-message控制器驱动、tooltip/dropdown 全面改用data-*-value属性、w-action控制器新增reset方法、Stimulus dialog 新增notifytarget 等。这也解释了下方升级注意事项中大量"旧 data 属性/旧事件名"被替换的现象——后台前端正在稳步走向以 Stimulus 为统一框架的架构。

亮点五:ModelViewSet 能力大幅增强

5.2 将SnippetViewSet的一批能力下沉到通用基类{class}~wagtail.admin.viewsets.model.ModelViewSet,使得开发者**无需把模型注册为 snippet** 也能获得完整的后台管理视图。仓库中ModelViewSet的实现位于 [wagtail/admin/viewsets/model.py](https://link.gitcode.com/i/939380eea044e7e93a6af4c7fc04a7db),其类属性直接印证了 5.2 的新能力,例如add_to_reference_index = True(默认注册引用索引)、inspect_view_enabled = False(默认关闭 inspect 视图)、list_per_page = 20` 等。

本次从SnippetViewSet迁移到ModelViewSet的内容包括:

  • SnippetViewSet的菜单注册机制迁移到基类ViewSet
  • 将模板覆盖机制、list_display迁移到ModelViewSet
  • list_filterfilterset_classsearch_fieldssearch_backend_namelist_exportexport_filenamelist_per_pageordering等属性迁移到ModelViewSet
  • 为通用IndexView/CreateView增加默认头部标题;
  • 通用IndexView支持使用过滤器与导出列表;
  • ModelViewSet新增通用UsageViewInspectView,并从 snippets 中提取通用HistoryView
  • 从页面面包屑中提取通用面包屑功能,并为自定义ModelViewSet视图提供面包屑支持;
  • 允许ModelViewSet用于非整数主键模型;
  • ModelViewSet注册的模型默认开启引用索引(reference index)追踪。

同时,以下新特性也加入了通用后台视图,SnippetViewSet同样可用:

  • 允许通过ModelViewSet覆盖IndexView.export_headings
  • 允许在通用IndexView上定义列表按钮(listing buttons)。

完整用法参见 generic views 文档。

亮点六:管理界面打磨与搜索推广外链

5.2 对后台用户界面做了一批细节打磨:页面状态侧栏的相对日期上以 tooltip 显示完整的首次发布时间、无面板锚点时不再渲染 minimap、dashboard 面板的列表改用下拉按钮、面包屑设计细化、表单提交与简单翻译提交支持 Shift + Click 批量行为、按用户权限优化审计日志过滤等。

另一个实用新特性是:推广搜索结果(Promoted Search Results)条目现在可以使用外部 URL 与自定义链接文本,而不再只能指向 Wagtail 内的页面,便于跨站点管理推广内容(感谢 TopDevPros 与芝加哥大学图书馆的 Brad Busenius)。

其他功能亮点速览

发布说明中的"Other features"包含一批值得关注的能力,择要列出:

  • 模板标签防缓存:新增wagtailcachewagtailpagecache模板标签,确保预览 Page 或 Snippet 时不会被缓存;
  • 视图限制随页面复制/别名迁移:复制页面或创建别名时,其视图限制(view restrictions)会一并复制到目标;
  • StreamField 值支持 pickle
  • Chooser 增强ChooserViewSet支持指定get_object_list方法;chooser widgets 新增linked_fields机制,可按调用页面的字段限制可选范围;
  • TableBlock 支持合并单元格:通过mergedCells选项实现;
  • InlinePanel 焦点与 DOM 事件:在InlinePanel内新增面板时焦点会移至新内容(与StreamField一致),并新增 ready/新增/移除等InlinePanelDOM 事件;
  • {% component %}标签支持传递额外上下文变量
  • API v2 支持多字段排序PagesAPIViewSet子类可通过model属性覆盖默认 Page 模型;
  • Email 链接 chooser 支持主题与正文
  • wagtail_update_image_renditions管理命令输出可视化进度条;
  • 上传文件哈希生成增大读缓冲区,并在 Python 3.11+ 使用hashlib.file_digest提升效率;
  • Block.get_template可接收value参数,允许按块值选择模板;
  • purge_revisions管理命令现在会尊重带on_delete=PROTECT外键关系的 revision,不再删除它们。

升级注意事项:影响所有项目

MariaDB 上的 UUID 字段与 Django 5.0

Django 5.0 在 MariaDB 10.7 及以上引入了对 MariaDB 原生 UUID 类型的支持,这会破坏旧版本 Django/MariaDB 创建的CHAR型 UUID 的向后兼容性。因此,将站点升级到 Django 5.0+ 与 MariaDB 10.7+ 后,创建或编辑页面时很可能出现类似Data too long for column 'translation_key' at row 1Data too long for column 'uuid' at row 1的错误。

修复方法是升级后运行(该命令自Wagtail 5.2.5起提供)convert_mariadb_uuids管理命令:

./manage.py convert_mariadb_uuids

该命令会把 Wagtail 使用的所有既有 UUID 字段转换为新格式。在 Django 5.0+ 与 MariaDB 10.7+ 下新建的站点不受影响,无需执行。

升级注意事项:旧功能弃用

旧版 moderation 系统弃用

在 Wagtail 2.10 被新工作流(workflow)系统取代的旧版 moderation 系统,如今正式标记为弃用。自 2.10 起提交的页面审核已走新工作流,但 2.10 之前提交、仍滞留在旧队列中的页面仍需通过旧系统批准/拒绝:

  • 以超级用户登录后台,可在仪表盘看到"Pages awaiting moderation"区块并操作;
  • 也可以编程处理:查询Revision.objects.filter(submitted_for_moderation=True),对每个 revision 调用revision.approve_moderation()revision.reject_moderation()

以下 API 与配置随之弃用,并将在未来版本移除(应替换为新工作流的对应能力):

  • wagtail.models.Revision.submitted_for_moderation
  • wagtail.models.Revision.submitted_revisions
  • wagtail.models.Revision.approve_moderation
  • wagtail.models.Revision.reject_moderation
  • RevisionMixin.save_revisionsubmitted_for_moderation参数
  • WAGTAIL_MODERATION_ENABLED
  • wagtail.admin.userbar.ModeratePageItemApproveModerationEditPageItemRejectModerationEditPageItem
  • wagtail.admin.views.home.PagesForModerationPanel
  • wagtail.admin.views.pages.moderation
  • wagtail.permission_policies.pages.PagePermissionPolicy.revisions_for_moderation

详情可回顾 Wagtail 2.10 发布说明。

升级注意事项:影响 Wagtail 定制代码

classname命名约定

Wagtail 从 4.2 开始推行统一的单数classname(而非复数classnames)约定,5.2 将这一约定扩展到菜单与钩子体系。以下类采用新约定:

  • admin.menu.MenuItem
  • admin.ui.sidebar.ActionMenuItem
  • admin.ui.sidebar.LinkMenuItem
  • admin.ui.sidebar.PageExplorerMenuItem
  • contrib.settings.registry.SettingMenuItem

以下钩子在使用classnames生成菜单项时可能受影响:register_admin_menu_itemregister_settings_menu_item(钩子完整清单见 hooks 参考)。

旧的classnames关键字仍可用但会触发弃用警告,未来版本将移除。示例(注意第 8 行使用classname=):

from django.urls import reverse from wagtail import hooks from wagtail.admin.menu import MenuItem @hooks.register("register_admin_menu_item") def register_frank_menu_item(): return MenuItem( "Frank", reverse("frank"), icon_name="folder-inverse", order=10000, classname="highlight-menu", # 不是 classnames=... )

ModelViewSet 的编辑/删除 URL 变更(支持非整数主键)

为支持非整数主键模型,ModelViewSet中编辑与删除视图的 URL 模式已变更。相对于视图集的url_prefix

  • 编辑 URL 由<int:pk>/改为edit/<str:pk>/
  • 删除 URL 由<int:pk>/delete/改为delete/<str:pk>/

若你通过django.urls.reverse配合get_url_name()生成 URL,无需改动;但若在代码中硬编码了这些 URL,必须更新。旧 URL 的重定向仅为向后兼容保留,未来版本会移除。SnippetViewSet中旧 URL 的重定向也已被标记为未来移除。

ModelViewSet 自动注册引用索引

通过ModelViewSet注册的模型默认启用引用索引追踪,不再需要在 app 的ready()方法中手动调用ReferenceIndex.register_model()。若不希望如此,可在ModelViewSet子类上设置add_to_reference_index = False(对应源码 wagtail/admin/viewsets/model.py)。详见 引用索引管理文档。

其他行为变更一览

  • GroupViewSetIndexView.results_template_name更名:由wagtailusers/groups/results.html改为wagtailusers/groups/index_results.html,自定义过该模板(如 自定义组视图)的项目需要同步重命名。

  • construct_snippet_listing_buttons钩子不再接受context参数:需要访问视图计算值的场景,应改为覆盖SnippetViewSet.index_view_class自定义IndexView(特别是get_list_buttonsget_list_more_buttons方法)。旧签名会触发警告并收到空字典{}

  • 页面列表/头部按钮钩子的page_perms参数被user取代

    • register_page_header_buttons:由func(page, page_perms, next_url)变为func(page, user, next_url, view_name),其中view_name'edit''index'
    • register_page_listing_buttons:变为func(page, user, next_url)
    • construct_page_listing_buttons:变为fn(buttons, page, user, context)
    • register_page_listing_more_buttons:变为func(page, user, next_url)
    • ButtonWithDropdownFromHook构造器同样改传user

    旧代码如需获取权限测试对象,可用page.permissions_for_user(user)替代。相关钩子说明见 hooks 参考。

升级注意事项:未文档化的内部变更

面包屑类名由单数改为复数

自定义面包屑样式时,类名'w-breadcrumb'已改为'w-breadcrumbs'

Snippets 模板重构为复用slim_header.html

以下 snippets 头部模板已被移除,绝大多数场景可用wagtailadmin/shared/headers/slim_header.html替代:

  • wagtailsnippets/snippets/headers/_base_header.html
  • create_header.htmledit_header.htmlhistory_header.htmllist_header.htmlusage_header.html

侧栏组合类移除

BaseSidePanelsPageSidePanelsSnippetSidePanels类已移除,每个侧栏现在直接在视图中实例化;BasePreviewSidePanel/PagePreviewSidePanel/SnippetPreviewSidePanel合并为PreviewSidePanelBaseStatusSidePanel更名为StatusSidePanel。媒体对象可用wagtail.admin.ui.components.MediaContainer组合。

旧写法:

from wagtail.admin.ui.side_panels import PageSidePanels def my_view(request): ... side_panels = PageSidePanels( request, page.get_latest_revision_as_object(), show_schedule_publishing_toggle=False, live_page=page, scheduled_page=page.get_scheduled_revision_as_object(), in_explorer=False, preview_enabled=True, comments_enabled=False, ) return render( request, template_name, {"page": page, "side_panels": side_panels, "media": side_panels.media}, )

新写法:

from wagtail.admin.ui.components import MediaContainer from wagtail.admin.ui.side_panels import PageStatusSidePanel, PreviewSidePanel def my_view(request): ... side_panels = [ PageStatusSidePanel( page, request, show_schedule_publishing_toggle=False, live_object=page, scheduled_object=page.get_scheduled_revision_as_object(), locale=page.locale, translations=translations, ), PreviewSidePanel( page, request, preview_url=reverse("wagtailadmin_pages:preview_on_edit", args=[page.id]), ), ] side_panels = MediaContainer(side_panels) return render( request, template_name, {"page": page, "side_panels": side_panels, "media": side_panels.media}, )

面包屑迁移到 Stimulus:事件与 data 属性变化

头部面包屑组件已迁移到 Stimulus 控制器,事件与 data 属性均发生变化(自定义头部实现、以及未使用breadcrumbs却依赖展开/收起行为的自定义面包屑可能受影响):

旧事件新事件
'wagtail:breadcrumbs-expand''w-breadcrumbs:opened'
'wagtail:breadcrumbs-collapse''w-breadcrumbs:closed'
旧 data 属性新 data 属性
data-breadcrumb-nextdata-controller="w-breadcrumbs"
data-toggle-breadcrumbsdata-w-breadcrumbs-target="toggle">window.updateFooterSaveWarning = (formDirty, commentsDirty) => { if (!formDirty && !commentsDirty) { document.dispatchEvent(new CustomEvent('w-unsaved:clear')); } else { const [type] = [ formDirty && commentsDirty && 'all', commentsDirty && 'comments', formDirty && 'edits', ].filter(Boolean); document.dispatchEvent(new CustomEvent('w-unsaved:add', { detail: { type } })); } };

其他内部变更速查

  • dropdown模板标签参数更名toggle_tippy_offset改为toggle_tooltip_offset,例如{% dropdown toggle_tooltip_offset="[0, -2]" %}...{% enddropdown %}
  • escapescript模板标签与escape_script函数弃用:它们是为已停止支持的 IE11 提供 HTML 模板内容转义,且不符合 CSP;请改用 HTML<template>元素避免内容被浏览器解析:
<template id="id_{{ formset.prefix }}-EMPTY_FORM_TEMPLATE"> <div>Widget template content</div> <script src="/js/my-widget.js"></script> </template>
  • 图片Format实例的classnames改为classname:自定义格式代码中访问self.classnames仍可返回self.classname,但会触发弃用警告,应改为self.classname
  • search promotions 模块调整search_garbage_collect管理命令已彻底移除(5.0 起迁移到searchpromotions_garbage_collect,见 管理命令文档);部分 URL 名称与模板从主 admin 搜索模块迁入 search promotions 模块,例如 URL 名称wagtailsearch_admin:queries_chooser改为wagtailsearchpromotions:chooser,chooser 相关模板路径相应迁移到 wagtail/contrib/search_promotions/ 模块内。
  • Block.get_template新增value参数:StreamField 块的get_template现在接收valuecontext,旧签名def get_template(self, context=None)应更新为def get_template(self, value=None, context=None)

结语

Wagtail 5.2 作为一个 LTS 版本,交出了相当扎实的成绩单:picture/srcset_image为全站图片体积与碳足迹带来立竿见影的改善,OpenSearch 补齐了搜索后端的可替代选择,ModelViewSet的能力下沉让"非 snippet 模型也能拥有完整后台"成为现实,Stimulus 的正式支持则标志着后台前端进入统一框架时代。与此同时,5.2 也集中清理了一大批历史包袱(旧版 moderation、classnamespage_perms钩子、旧侧栏组合类等),升级时需要对照本文的变更清单逐一核对自定义代码。若你的项目正计划长期维护,5.2 LTS 系列是当前值得认真评估的稳定基线。

【免费下载链接】wagtailA Django content management system focused on flexibility and user experience项目地址: https://gitcode.com/GitHub_Trending/wa/wagtail

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询