ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Django Oscar 1.5.2 修复版发布说明:AdvancedSelect 的 Django 1.11 兼容修复与 TinyMCE 本地化

Django Oscar 1.5.2 修复版发布说明:AdvancedSelect 的 Django 1.11 兼容修复与 TinyMCE 本地化 后端电商【免费下载链接】django-oscarDomain-driven e-commerce for Django项目地址https://gitcode.com/gh_mirrors/dj/django-oscar点击查看免费下载本文是 Django Oscar 1.5 维护分支的补丁版本2018-02-12 发布技术解析。1.5.2 是一次纯粹的 Bug Fix 发布重点解决两个直接影响后台与购物车体验的问题AdvancedSelect表单组件在 Django 1.11 及以上版本中的渲染异常以及仪表盘富文本编辑器 TinyMCE 从 CDN 引用改为本地静态资源托管。读完本文你将理解这两个问题的成因、Oscar 源码中的修复实现以及如何在自己的 Oscar 项目中验证与升级。1. 版本定位一次聚焦稳定性的维护发布Oscar 1.5.2 隶属于 1.5 release 分支该分支的完整发布序列为 1.5、1.5.1、1.5.2、1.5.3、1.5.4见 docs/source/releases/index.rst。官方发布说明明确将其定性为bug fix release不引入新特性也不包含向后不兼容的变更主要目标是为已部署在 Django 1.11 环境中的 Oscar 项目提供稳定性保障。1.5 主线版本docs/source/releases/v1.5.rst当时官方支持的 Django 版本为 1.8、1.10、1.11以及 Python 2.7、3.3、3.4、3.5、3.6。1.5.2 的两个修复点恰好都落在升级到 Django 1.11 后的场景上属于典型的大版本兼容性收尾工作。2. 修复一AdvancedSelect 组件在 Django 1.11 下的行为异常2.1 问题背景发布说明原文指出Fixedoscar.core.widgets.AdvancedSelectwidget behaviour with Django 1.11 and above.AdvancedSelect是 Oscar 在 Django 原生Select组件基础上扩展的自定义下拉框核心能力是支持传入一组禁用选项disabled values使特定选项在渲染时带上disabled属性。Django 1.11 重构了选项渲染的内部 API旧的render_option方法被弃用取而代之的是create_option。Oscar 1.5.2 之前对该组件基于旧 API 的实现在 Django 1.11 上渲染行为出现偏差因此需要针对新 API 重写渲染逻辑。2.2 源码中的修复实现需要说明的是发布说明中的类路径oscar.core.widgets.AdvancedSelect对应的是 1.5.x 时代的模块布局在当前仓库中该组件位于 src/oscar/forms/widgets.py实现如下class AdvancedSelect(forms.Select): Customised Select widget that allows a list of disabled values to be passed to the constructor. Djangos default Select widget doesnt allow this so we have to override the render_option method and add a section that checks for whether the widget is disabled. def __init__(self, attrsNone, choices(), disabled_values()): self.disabled_values set(force_str(v) for v in disabled_values) super().__init__(attrs, choices) def create_option( self, name, value, label, selected, index, subindexNone, attrsNone ): option super().create_option( name, value, label, selected, index, subindex, attrs ) if force_str(value) in self.disabled_values: option[attrs][disabled] True return option修复的关键点在于构造函数接收disabled_values以可迭代对象传入需要禁用的值内部统一转为set并做force_str归一化避免类型不一致导致的匹配失败。重写create_option而非旧的render_option这是与 Django 1.11 兼容的核心。create_option是 Django 1.11 引入的新选项渲染钩子返回字典形式的 option 描述Oscar 在父类生成的结果上追加option[attrs][disabled] True从而在渲染 HTML 时输出option ... disabled。类文档字符串仍保留对render_option的描述但实际实现已完全切换到新 API——这正是 1.5.2 修复落地后的代码形态。2.3 组产品Group Product中的实际应用AdvancedSelect并非孤立组件它在购物篮表单中被实际用于组产品parent product的变体选择。在 src/oscar/apps/basket/forms.py 的_create_parent_product_fields方法中def _create_parent_product_fields(self, product): choices [] disabled_values [] for child in product.get_public_children(): # Build a description of the child, including any pertinent attributes attr_summary child.attribute_summary if attr_summary: summary attr_summary else: summary child.get_title() # Check if it is available to buy info self.basket.strategy.fetch_for_product(child) if not info.availability.is_available_to_buy: disabled_values.append(child.id) choices.append((child.id, summary)) self.fields[child_id] forms.ChoiceField( choicestuple(choices), label_(Variant), widgetwidgets.AdvancedSelect(disabled_valuesdisabled_values), )这里的业务逻辑是遍历组产品的所有公开子产品get_public_children()通过basket.strategy.fetch_for_product(child)获取其购买可用性若子产品当前不可购买缺货、下架等就将其 id 追加进disabled_values最终由AdvancedSelect在渲染变体Variant下拉框时把不可购买项置灰。这样用户只能选择有货的变体从交互层面提前拦截无效选择——该能力在修复前依赖旧的渲染路径Django 1.11 下会失效或产生异常输出因此这属于直接影响购物车可用性的关键修复。2.4 测试验证仓库中的集成测试对修复后的行为做了明确断言见 tests/integration/forms/test_widget.py 的AdvancedSelectWidgetTestCaseclass AdvancedSelectWidgetTestCase(TestCase): def test_widget_disabled_options(self): choices ( (red, Red), (blue, Blue), (green, Green), ) disabled_values (red, green) i widgets.AdvancedSelect(choiceschoices, disabled_valuesdisabled_values) html i.render(advselect, []) self.assertInHTML(option valueblueBlue/option, html, count1) self.assertInHTML(option valuered disabledRed/option, html, count1) self.assertInHTML( option valuegreen disabledGreen/option, html, count1 )该用例覆盖三条断言未被禁用的选项正常渲染、被禁用的选项输出disabled属性且计数准确。升级到 1.5.2或包含该修复的后续版本后可运行pytest tests/integration/forms/test_widget.py验证组件行为。3. 修复二TinyMCE 由 CDN 改为本地静态资源3.1 问题背景发布说明原文指出Use a local copy of TinyMCE instead of a CDN, because of recent bugs in the CDN.Oscar 仪表盘的富文本编辑功能基于 TinyMCE。此前版本通过 CDN 加载 TinyMCE 脚本由于 CDN 近期出现稳定性/内容问题1.5.2 改为随包分发 TinyMCE 的本地副本从模板中移除 CDN 引用彻底消除对第三方 CDN 可用性的运行时依赖。3.2 本地化在当前仓库中的完整落地虽然当前仓库已演进到 Oscar 4.x但TinyMCE 本地托管这一设计被完整保留可以从多个层面印证1前端依赖声明package.json 将 TinyMCE 及其 jQuery 集成插件列为 npm 开发依赖tinymce: ^7.9.1, tinymce/tinymce-jquery: ^2.1.02构建期复制到静态目录gulpfile.js/subtasks/copy.js 通过 gulp 任务把 npm 包中的 TinyMCE 资源拷贝到 Oscar 自身的静态目录gulp.src([ node_modules/tinymce/**/*.min.js, node_modules/tinymce/**/*.min.css, node_modules/tinymce/**/fonts/*, node_modules/tinymce/**/img/*, ]).pipe(gulp.dest(src/oscar/static/oscar/js/tinymce/)); gulp.src([ node_modules/tinymce/tinymce-jquery/dist/tinymce-jquery.min.js ]).pipe(rename(jquery.tinymce.min.js)).pipe(gulp.dest(src/oscar/static/oscar/js/tinymce/));可以看到脚本、样式、字体、图片全部被纳入本地拷贝范围且tinymce/tinymce-jquery的入口文件被重命名为jquery.tinymce.min.js与模板中的静态引用名保持一致。这正是Use a local copy of TinyMCE instead of a CDN在工程层面的具体落实方式npm install之后运行npm run build内部执行gulp copy gulp scss即可完成资源本地化。3模板引用本地静态文件src/oscar/templates/oscar/dashboard/layout.html 中不再出现任何 CDN 域名全部通过 Django 静态文件机制加载本地副本script src{% static oscar/js/tinymce/tinymce.min.js %}/script script src{% static oscar/js/tinymce/jquery.tinymce.min.js %}/script4前端初始化逻辑src/oscar/static_src/oscar/js/oscar/dashboard.js 的initWYSIWYG对带有wysiwyg类或位于form.wysiwyg内的 textarea 统一调用 TinyMCE 初始化并使用内置的tinyConfiginitWYSIWYG: function(el) { // Use TinyMCE by default var $textareas $(el).find(textarea).not(.no-widget-init textarea).not(.no-widget-init); $textareas.filter(form.wysiwyg textarea).tinymce(o.dashboard.options.tinyConfig); $textareas.filter(.wysiwyg).tinymce(o.dashboard.options.tinyConfig); },配套的tinyConfigdashboard.js开启了entity_encoding: raw、convert_urls: false、link/lists插件并隐藏菜单栏与状态栏工具栏仅保留styles | bold italic blockquote | bullist numlist | link以保证后台编辑区的轻量输出。5服务端控件配对表单侧由 src/oscar/forms/widgets.py 的WYSIWYGTextArea提供支持它给 textarea 自动追加wysiwyg类从而被上述前端初始化逻辑命中class WYSIWYGTextArea(forms.Textarea): def __init__(self, *args, **kwargs): kwargs.setdefault(attrs, {}) kwargs[attrs].setdefault(class, ) kwargs[attrs][class] wysiwyg super().__init__(*args, **kwargs)至此形成完整的闭环表单控件打上wysiwyg标记 → 模板加载本地 TinyMCE 脚本 → dashboard.js 初始化编辑器全程不依赖外部 CDN。4. 升级到 1.5.2 的落地建议结合上述两个修复从 1.5.1 及更早版本升级到 1.5.2 时建议按以下步骤操作升级依赖并重建静态资源执行pip install django-oscar1.5.2随后在项目内重新收集静态文件python manage.py collectstatic确保oscar/js/tinymce/下的本地 TinyMCE 文件被正确拷贝到你的静态目录。若你自行维护前端构建流程需参考 gulpfile.js/subtasks/copy.js 将 TinyMCE 资源纳入拷贝任务。回归验证购物车变体选择针对使用组产品group product的商品验证变体Variant下拉框中不可购买的子产品是否显示为置灰不可选状态并运行 tests/integration/forms/test_widget.py 确认AdvancedSelect渲染正常。回归验证后台富文本编辑进入 dashboard 的富文本编辑页面如通信模板、页面内容等使用WYSIWYGTextArea的表单确认 TinyMCE 编辑器在无外网环境下也能正常加载与保存内容且控制台无 CDN 资源加载失败报错。留意 CDN 相关自定义若你的项目此前在模板中自行覆盖了 TinyMCE 的 CDN 引用例如重写了dashboard/layout.html请同步移除外部脚本标签改为引用本地静态路径{% static oscar/js/tinymce/tinymce.min.js %}。1.5.2 之后的 1.5.3、1.5.4 以及 1.6 分支继续承载了后续的维护工作完整的发布历史见 docs/source/releases/index.rst但 1.5.2 所解决的两个问题——表单组件对 Django 新渲染 API 的适配、以及前端资源对第三方 CDN 的解耦——至今仍是 Oscar 源码中稳定延续的设计决策。赞分享后端电商【免费下载链接】django-oscarDomain-driven e-commerce for Django项目地址https://gitcode.com/gh_mirrors/dj/django-oscar点击查看免费下载相关推荐WeChatMsg 完整速览指南如何用 4 步把微信聊天记录导出为 HTML、Word 与 CSVWeChatMsg 完整速览指南如何用 4 步把微信聊天记录导出为 HTML、Word 与 CSV WeChatMsg 是一款用于提取微信聊天记录的开源工具用Voyager文件夹驯服混乱的AI对话拖拽、嵌套与自定义颜色的完整组织指南用Voyager文件夹驯服混乱的AI对话拖拽、嵌套与自定义颜色的完整组织指南 Voyager 是一款面向 Gemini、AI Studio、Claude 与后端WebSocket异步编程django-oscar 1.4 版本解析Django 1.10 兼容性升级与核心修复全览django oscar 1.4 版本解析Django 1.10 兼容性升级与核心修复全览 导读 django oscar 1.4 是一个以「兼容性升级」为主后端电商上一篇Argos Translate 离线翻译排错指南从装不上到跑得快的 5 个常见卡点下一篇一键 AI 抠像换背景OBS 背景移除插件 obs-backgroundremoval 的 3 步实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表