django CMS 5.0.7 升级指南Django 4.2–6.0 兼容矩阵、迁移步骤与 15 项 Bug 修复源码级解析【免费下载链接】django-cmsThe easy-to-use and developer-friendly enterprise CMS powered by Django项目地址: https://gitcode.com/gh_mirrors/dj/django-cmsdjango CMS 5.0.7 是 django CMS 5.x 系列的一次维护性版本主要面向从 django CMS 4.1 及更早版本升级的用户集中修复了结构模式切换、插件 downcast、权限校验、XSS 安全、大页面子树移动死锁等十余个实际问题。阅读本文后你将掌握 5.0.7 的完整兼容范围、标准升级路径并能从源码层面理解每一项修复的成因、影响面与验证方式为你的项目升级与回归测试提供直接依据。版本概览Django 与 Python 兼容性矩阵django CMS 5.0.7 的官方支持范围在发布说明中有明确界定升级前请先确认项目技术栈落在以下区间运行时受支持版本官方建议Django4.2、5.0、5.1、5.2、6.0强烈建议使用每个系列的最新补丁版Python3.10、3.11、3.12、3.13强烈建议使用每个系列的最新补丁版需要特别注意的是官方口径是高度推荐且仅支持每个系列的最新发布版highly recommend and only support the latest release of each series即 Django 4.2 系列应尽量使用 4.2 的最新小版本Python 同理。这一口径意味着若你的项目仍停留在较旧的 Django 补丁版虽然理论上可运行但不在官方保障范围内升级前应优先把 Django 与 Python 升级到对应系列的最新补丁。仓库中与版本兼容性相关的测试要求文件如 test_requirements/django-5.2.txt、test_requirements/django-6.0.txt、test_requirements/django-6.1.txt也从侧面印证了项目对多版本 Django 的持续测试投入。如何升级到 5.0.7发布说明给出的升级路径非常标准共两步第一步更新依赖并安装编辑项目的requirements.txt将 django CMS 版本约束提高到至少 5.0.7django-cms5.0.7然后执行pip install -r requirements.txt第二步运行数据库迁移python -m manage migrate注意发布说明使用python -m manage migrate的调用形式等价于常见的python manage.py migrate这种方式不依赖系统 PATH 中是否注册了 manage.py在虚拟环境中更稳妥。跨版本升级的额外要求如果你是从更早的 django CMS 版本升级而来发布说明明确要求阅读当前版本到 5.0.7 之间所有版本的发布说明参见 docs/upgrade/index.rst逐一检查是否存在特殊说明如数据迁移、配置变更、废弃特性。5.0.7 的发布说明同时提醒项目已开始对部分特性启动废弃deprecation流程跨版本升级时需留意 4.x→5.x 的破坏性变更。5.0.7 更新内容详解本版本共合入 15 个 Pull Request贡献者名单集中在 Fabian Braun15 个 PR审阅者为 Vinit Kumar。下面按功能域对每一项修复进行展开并结合仓库源码说明其技术背景。编辑体验与前端行为修复1. 切换结构模式时保留 GET 参数#8497此前在工具栏中切换结构模式/内容模式时URL 上携带的查询参数如语言、筛选、预览参数等会被丢弃导致编辑上下文丢失。修复后结构模式切换会保留原有 GET 参数。相关的前端实现位于 cms/static/cms/js/modules/cms.structureboard.js结构模式的开/关逻辑以及 cms/static/cms/js/modules/cms.base.js其中通过searchParams.set/delete维护查询参数的工具方法URL 参数处理正是复用这类基于URLSearchParams的能力。2. DiffDOM 偶发残留损坏的 head 区块#8562前端 DOM 差异更新diffing负责在编辑器内局部刷新页面而避免整页重载。此前在某些更新序列下head区域会出现残留的损坏内容。django CMS 在 cms/static/cms/js/modules/dom-diff.js 中自带了一个轻量的 DiffDOM 实现export class DiffDOM并在 cms/static/cms/js/modules/cms.structureboard.js 中实例化使用dd new DiffDOM()。该修复针对 head 区块的 diff 行为进行了收紧升级后建议在编辑器中反复切换结构/内容模式做回归验证。3. 删除非本地non-local插件后页面未刷新#8582在多语言或多占位符场景下删除一个非本地插件例如通过语言复制产生的插件后前端未能及时刷新视图用户会看到已删除的插件仍停留在页面上。本次修复确保删除操作后屏幕得到正确刷新前端插件操作逻辑可参考 cms/static/cms/js/modules/cms.plugins.js。4. apphook 页面在前端编辑模式下 page_title 为空#8449挂载了 apphook应用挂接的页面在编辑前端页面时page_title用于 HTMLtitle标签的覆盖标题解析为空。修复后该场景下page_title能被正确解析并渲染。插件系统与渲染修复5. 插件 QuerySet.iterator() 缺失 chunk_size#8532QuerySet.iterator()在 Django 中默认按数据库驱动的 chunk 大小分批取数但显式指定chunk_size可以控制每次迭代拉取的行数直接影响内存占用与 SQL 批次数。修复前部分插件查询路径调用iterator()时未传chunk_size。从源码看django CMS 在 cms/constants.py 中定义了默认值#: Default chunk_size for QuerySet.iterator() calls on plugin querysets. PLUGIN_ITERATOR_CHUNK_SIZE 2000并在cms.utils.plugins的两个关键函数中使用get_bound_pluginscms/utils/plugins.py与downcast_pluginscms/utils/plugins.pyfor instance in plugin_queryset.iterator(chunk_sizePLUGIN_ITERATOR_CHUNK_SIZE):对应的测试位于 cms/tests/test_plugins.pytest_iterator_chunk_size_in_get_bound_plugins通过 patch 掉 queryset 的iterator方法断言其收到的chunk_size等于预期值测试中使用 999 进行校验从而保证该行为在后续重构中不被回退。6. CMSPlugin 的 Proxy 模型 downcast 不正确#8539django CMS 的插件体系允许通过 proxy 模型模型代理扩展CMSPlugin。downcast向下转型指把查询得到的基类CMSPlugin实例转换为实际注册插件对应的子类实例以便访问插件专属字段。修复前proxy 模型在 downcast 过程中没有被正确还原为代理类型。以 cms/utils/plugins.py 的downcast_plugins为例其核心逻辑是先把插件按plugin_type映射到具体模型再批量查询并逐个instance.__class__ cls.model完成类型还原cls.model即插件类对应的模型包含 proxy 情形。修复保证了包括 proxy 模型在内的所有插件类型都能正确 downcast。7. 未重定向时回退语言渲染为空#8558多语言站点中当页面在请求语言下不存在、且配置为不重定向而是直接渲染回退语言内容时回退语言的页面被渲染成空内容。本次修复恢复了该场景下的正确渲染行为相关配置可参考 docs/how_to/02-languages.rst 中关于语言回退的说明。权限与安全修复8. 行内编辑可绕过权限校验#8542这是本版本最值得关注的安全相关修复之一此前某些行内编辑inline editing路径存在权限校验缺口未授权用户可能借此绕过权限限制修改内容。插件与占位符的编辑、校验逻辑集中在 cms/admin/placeholderadmin.py其职责在文件注释中明确为manages placeholders and their plugins, as well as the preview, edit, and …见该文件约 L199-L244。升级后建议对行内编辑相关权限做针对性回归测试。9. 校验器错误消息中的 XSS 漏洞#8576URL 唯一性校验等场景会生成包含页面标题链接的错误消息若消息中的标题等内容未经转义直接以 HTML 形式输出攻击者可注入脚本XSSCWE-79。从 cms/forms/validators.py 的实现看validate_url的注释明确记载了这类风险relative_url_regex只约束相对路径的字符集并不限制首个斜杠之前的部分因此javascript:alert(1)/x、data:text/html,...这类值既能通过相对分支校验、又携带可执行脚本的 scheme。修复在 cms/forms/validators.py 增加了 scheme 检查if urlsplit(value).scheme: raise ValidationError( gettext(Enter a valid relative or absolute URL.), codeinvalid, )同时在validate_url_uniqueness中构造冲突链接时使用escape()转义标题与路径见 cms/forms/validators.pydjango.utils.html.escape与mark_safe的搭配使用保证了链接本身安全、内容被转义。这是典型的纵深防御既拦截恶意 scheme又对输出内容做 HTML 转义。管理与 API 修复10. 只读 change_view 中 slug 与 overwrite_url 缓存失败#8509在只读的变更视图read-only change view中slug与overwrite_url的缓存未正确生效导致每次访问都重新计算路径。该修复补齐了只读场景下的缓存行为与页面 URL 模型PageUrl见 cms/models/pagemodel.py的路径生成逻辑相关。11.cms.api.create_page新增page_title参数#8572create_page是 django CMS 最核心的编程式建页 API。此前通过 Python API 创建页面时无法直接指定page_titleHTMLtitle标签的覆盖标题本次为 cms/api.py 的create_page增加了该参数def create_page( title, template, language, menu_titleNone, slugNone, ... page_titleNone, ):其文档注释明确说明page_title为 Overridden page title for HTML title tag见 cms/api.py且该值会被透传给create_page_content见 cms/api.py后者同样具备page_title参数。编程式创建页面如迁移脚本、导入工具、测试夹具现在可以在建页时一并写入 SEO 标题无需事后二次更新。12.Page.objects.order_by兼容垫片引用不存在的字段#8598为兼容旧调用方式提供的order_by垫片compatibility shim引用了不存在的字段在特定排序场景下会抛出异常。本次修复纠正了垫片中的字段引用。13.ApplicationConfigSelect未将值转为字符串#8601apphook 配置选择控件ApplicationConfigSelect位于 cms/forms/widgets.py 附近在取值比较时未将值统一转换为字符串导致类型不一致引发的匹配失败。修复后控件会比较字符串形式的值。14. 自定义用户模型下的迁移导致 ProgrammingError#8608项目使用自定义用户模型AUTH_USER_MODEL时某些迁移在生成 SQL 阶段引用了不存在的用户相关字段抛出 ProgrammingError。本次修复使迁移在自定义用户模型场景下也能正确执行。这与 cms/models/permissionmodels.py 中权限模型对用户模型的外键依赖有关升级时建议在自定义用户模型的测试项目上跑一次完整的migrate。15. 移动大型页面子树可能发生死锁#8610在页树中移动包含大量子节点的子树时数据库事务可能因锁顺序问题发生死锁。django CMS 的页面树基于 MPTT 风格实现相关工具见 cms/utils/mptree.py大子树移动涉及批量更新节点位置锁竞争概率随之上升。本次修复调整了移动操作的执行方式以规避死锁。如果你的站点存在深且宽的页面树升级后应对移动大子树做一次压力回归。杂项修复外部占位符缺少固定pin图标#8520前端编辑器中外部占位符external placeholder即由第三方应用提供、通过PlaceholderField等关联到非页面对象的占位符缺少用于固定/取消固定的图标本次补充了该图标补齐了占位符工具栏的交互完整性。升级回归建议综合 5.0.7 的修复面升级完成后建议按以下清单做回归验证前端编辑切换结构/内容模式时确认 URL 查询参数保留反复切换后页面head区域无残留脏内容删除非本地插件后界面即时刷新。多语言验证未重定向场景下回退语言页面能正确渲染docs/how_to/02-languages.rst。安全在页面/重定向 URL 校验中输入带 scheme 的恶意值如javascript:alert(1)/x确认被拒绝制造 URL 冲突确认错误消息中的页面标题已被转义。权限对行内编辑路径做权限回归确认未授权请求被拦截。数据与迁移在自定义用户模型的测试环境跑python -m manage migrate对大型页面树执行移动操作验证无死锁。API使用cms.api.create_page时传入新的page_title参数确认 HTMLtitle输出正确。以上各项均可在本仓库对应的测试与源码cms/tests、cms/api.py、cms/utils/plugins.py、cms/forms/validators.py、cms/static/cms/js/modules中找到实现依据便于你结合具体项目场景做定向验证。【免费下载链接】django-cmsThe easy-to-use and developer-friendly enterprise CMS powered by Django项目地址: https://gitcode.com/gh_mirrors/dj/django-cms创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考