资讯动态

InvenTree 插件导航扩展指南:使用 NavigationMixin 为系统头部添加自定义导航链接

发布时间:2026/9/17 8:45:28 来源:尧图企业网站定制
InvenTree 插件导航扩展指南使用 NavigationMixin 为系统头部添加自定义导航链接【免费下载链接】InvenTreeOpen Source Inventory Management System项目地址: https://gitcode.com/GitHub_Trending/in/InvenTree导读本文聚焦 InvenTree 开源库存管理系统的插件体系深入讲解NavigationMixin导航混入的用法如何在插件中声明一组导航链接使其自动出现在 InvenTree 界面顶部的导航栏中并自定义父级导航节点的名称与图标。读完本文你将掌握NAVIGATION、NAVIGATION_TAB_NAME、NAVIGATION_TAB_ICON三个类常量的完整配置规则、URL 命名空间的约束条件以及混入机制在源码中的校验逻辑与测试验证方式可直接在自己的插件中落地实现导航扩展。1. NavigationMixin 是什么NavigationMixin是 InvenTree 插件体系中用于“往界面顶部导航栏添加链接”的混入类官方将其定义为 “Mixin that enables custom navigation links with the plugin”参见 NavigationMixin 源码。它的典型应用场景是当你编写了一个带独立页面如配置面板、统计看板的插件时希望在系统导航头部提供一个可点击的入口让用户能直接跳转到该插件的页面。从架构上看NavigationMixin属于 plugin/mixins 聚合模块 统一导出的混入之一可与AppMixin、SettingsMixin、UrlsMixin等其他混入自由组合使用。核心机制很简单混入在插件初始化时读取类常量NAVIGATION校验每个导航项的合法性然后暴露给 UI 层渲染。2. 最小可用示例向导航栏添加一个链接官方文档给出的最小实现如下本节代码原文引自 navigation.mdclass MyNavigationPlugin(NavigationMixin, InvenTreePlugin): NAME NavigationPlugin NAVIGATION [ {name: SampleIntegration, link: plugin:sample:hi, icon: ti ti-box}, ] NAVIGATION_TAB_NAME Sample Nav NAVIGATION_TAB_ICON ti ti-plus-circle2.1NAVIGATION的字段要求NAVIGATION必须是一个数组list数组内至少包含一个字典且每个字典必须同时包含name与link两个键否则混入初始化时会抛出异常详见第 4 节源码校验键是否必填作用name必填导航项在头部显示的文字link必填导航跳转目标使用 Django URL pattern 名称name lookup不能直接写外部网址icon可选导航项前显示的图标值为 CSS 图标类名如ti ti-box2.2link的格式约束为什么不能填外部链接link必须是“可被 Django 反向解析的 URL pattern 名称”。这一点是由插件 URL 机制决定的插件的内部 URL 命名空间统一为plugin:slug:前缀见 UrlsMixin 源码其internal_name属性直接返回fplugin:{self.slug}:。因此官方示例中的plugin:sample:hi表示跳转到 slug 为sample的插件中名为hi的 URL 路由。这意味着目标页面必须由 InvenTree 内的 URL pattern 提供。若想导航到插件自己的页面需要同时使用UrlsMixin声明路由并在link中使用plugin:slug:route_name的形式。2.3 父级导航节点NAVIGATION_TAB_NAME与NAVIGATION_TAB_ICONNAVIGATION_TAB_NAME与NAVIGATION_TAB_ICON是可选类常量用于修改“父级导航节点”的显示名称与图标。所谓父级节点即这些链接在导航头部分组的容器Tab。不设置时源码提供了兜底行为NAVIGATION_TAB_NAME默认为None此时混入的navigation_name属性会回退到插件的人类可读名称self.human_name见 NavigationMixin 源码NAVIGATION_TAB_ICON默认为fas fa-question见 NavigationMixin 源码属性navigation_icon亦以此作为最终兜底值。因此示例中NAVIGATION_TAB_NAME Sample Nav、NAVIGATION_TAB_ICON ti ti-plus-circle是可省略的——省略后系统将使用插件名与默认问号图标。3. 实战让导航链接真正可跳转结合 UrlsMixin由于link只能使用 URL pattern 名称一个可用的导航插件必须搭配UrlsMixin提供实际路由。仓库自带的官方示例插件提供了完整的可运行范例见 sample.pyfrom plugin import InvenTreePlugin from plugin.mixins import AppMixin, NavigationMixin, SettingsMixin, UrlsMixin class SampleIntegrationPlugin( AppMixin, SettingsMixin, UrlsMixin, NavigationMixin, InvenTreePlugin ): A full plugin example. NAME SampleIntegrationPlugin SLUG sample TITLE Sample Plugin NAVIGATION_TAB_NAME Sample Nav NAVIGATION_TAB_ICON fas fa-plus def view_test(self, request): Very basic view. return HttpResponse(fHi there {request.user.username} this works) def setup_urls(self): Urls that are exposed by this plugin. he_urls [ path(he/, self.view_test, namehe), path(ha/, self.view_test, nameha), ] return [ path(hi/, self.view_test, namehi), path(ho/, include(he_urls), nameho), ] NAVIGATION [{name: SampleIntegration, link: plugin:sample:hi}]该示例完整呈现了导航功能落地的全部要素SLUG sample决定了 URL 命名空间前缀为plugin:sample:setup_urls()通过UrlsMixin声明了hi/、ho/、he/、ha/等路由其中路由hi的完整 pattern 名称正是plugin:sample:hiNAVIGATION [{name: SampleIntegration, link: plugin:sample:hi}]将导航项直接指向该路由点击后即可访问view_test视图返回的页面。值得注意的是官方文档示例中导航项使用图标ti ti-box而仓库内置示例使用fas fa-plus二者均来自常见的图标字体类名体系说明icon字段对具体图标库无强绑定只要类名在 InvenTree 前端已加载的图标字体中存在即可渲染。4. 源码级原理初始化校验与属性解析深入 NavigationMixin 实现 可以看到其底层逻辑class NavigationMixin: Mixin that enables custom navigation links with the plugin. NAVIGATION_TAB_NAME None NAVIGATION_TAB_ICON fas fa-question def __init__(self): Register mixin. super().__init__() self.add_mixin(PluginMixinEnum.NAVIGATION, has_navigation, __class__) self.navigation self.setup_navigation() def setup_navigation(self): Setup navigation links for this plugin. nav_links getattr(self, NAVIGATION, None) if nav_links: # check if needed values are configured for link in nav_links: if False in [a in link for a in (link, name)]: raise MixinNotImplementedError(Wrong Link definition, link) return nav_links property def has_navigation(self): Does this plugin define navigation elements. return bool(self.navigation)从中可以总结出三个关键实现事实注册机制构造时通过add_mixin(PluginMixinEnum.NAVIGATION, has_navigation, __class__)把混入注册进插件注册表混入元数据MIXIN_NAME Navigation Links用于插件配置界面的能力展示逐项校验setup_navigation()遍历NAVIGATION中每个字典只要其中缺失link或name任一键立即抛出MixinNotImplementedError(Wrong Link definition, link)从源头杜绝“残缺导航项”进入界面惰性判定has_navigation属性返回bool(self.navigation)即未声明NAVIGATION时该插件不参与导航渲染不影响其他功能。5. 测试验证正确配置与错误配置的边界仓库在 test_mixins.py 中为NavigationMixin提供了专门测试类NavigationMixinTest清晰界定了合法与非法配置的边界class NavigationMixinTest(BaseMixinDefinition, TestCase): Tests for NavigationMixin. MIXIN_HUMAN_NAME Navigation Links MIXIN_NAME navigation MIXIN_ENABLE_CHECK has_navigation def setUp(self): class NavigationCls(NavigationMixin, InvenTreePlugin): NAVIGATION [{name: aa, link: plugin:test:test_view}] NAVIGATION_TAB_NAME abcd1 self.mixin NavigationCls() class NothingNavigationCls(NavigationMixin, InvenTreePlugin): pass self.nothing_mixin NothingNavigationCls() def test_function(self): Test that a correct configuration functions. self.assertEqual( self.mixin.navigation, [{name: aa, link: plugin:test:test_view}] ) self.assertEqual(self.mixin.navigation_name, abcd1) self.assertEqual(self.nothing_mixin.navigation_name, ) def test_fail(self): Test that wrong links fail. with self.assertRaises(NotImplementedError): class NavigationCls(NavigationMixin, InvenTreePlugin): NAVIGATION [aa, aa] NavigationCls()测试揭示了三个值得开发者注意的行为正确配置被原样保留navigation属性按原样返回NAVIGATION列表且navigation_name返回自定义的NAVIGATION_TAB_NAME未配置时优雅降级不声明任何导航常量的插件其navigation_name返回空字符串此时将回退使用插件的人类可读名称且has_navigation为False错误配置直接抛异常当NAVIGATION的元素不是字典如示例中的普通字符串aa时link in link判断失败初始化即抛出NotImplementedError——这是定位“导航不显示”问题时最典型的报错入口。测试基类中的MIXIN_ENABLE_CHECK has_navigation也印证了注册表正是通过has_navigation判定插件是否具备导航能力。6. 常见问题与排查建议导航链接点击 404 / 无法解析确认link使用的 URL pattern 名称拼写正确格式应为plugin:slug:route_name其中slug必须与插件的SLUG一致route_name必须是setup_urls()中path(..., name...)声明的名称无法直接跳转外部网站这是设计约束link只接受 URL pattern 名称不支持https://...形式如需跳转外部服务应在本插件内实现一个重定向视图后再进行导航初始化报NotImplementedError/MixinNotImplementedError检查NAVIGATION中的每个元素是否为包含name与link键的字典不要使用普通字符串或缺失键的字典图标不显示icon为可选字段请确认图标类名如ti ti-box、fas fa-plus在当前主题已加载的图标字体中存在导航未出现在头部确认插件已启用、且混入正常注册has_navigation为真未声明NAVIGATION时插件不会产生任何导航项。7. 相关资源官方文档Navigation Mixin混入实现源码NavigationMixin.py统一混入导出入口plugin/mixins/init.py完整可运行示例sample.py单元测试test_mixins.py插件 URL 命名空间来源UrlsMixin.py【免费下载链接】InvenTreeOpen Source Inventory Management System项目地址: https://gitcode.com/GitHub_Trending/in/InvenTree创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价