当前位置: 首页 > news >正文

如意 Django CRM 架构复盘:Django Admin 为什么不该自动绑定租户

OK,OK,大家好,欢迎大家来到大鹏 AI 教育,我是张大鹏。

这次我们不讲一个新页面。

我们复盘一个比页面更重要的问题:

Django Admin 到底是谁在用,它应该看到哪个范围的数据?

如意 CRM 是多租户系统。

最初做 Admin 首页时,我把业务端的组织会员关系带了进来。

系统从管理员的Profile推断唯一组织,再按组织展示指标。

没有Profile或同时属于多个组织时,首页数据就会消失。

这个实现看起来很“安全”,实际上混淆了两种后台。

真正需要修复的不是一条查询,而是 Django Admin 的架构边界。

一、从错误的单组织首页发现边界问题

问题始于一段合理但前提错误的多租户推断。

1.1 为什么看似安全的租户推断其实错位

错误思路并不复杂:CRM 是多租户系统,任何入口都应先得到当前组织。

但这句话漏掉了一个前提:不同入口面对的使用者并不相同。

先看两条路径的分叉点。

问题并不是有没有org,而是谁有权决定它。

为什么左侧越努力寻找“唯一组织”,越容易挡住合法管理员?

原因在于它使用了业务会员关系解释平台身份。

  • 🔍业务入口:租户员工依靠组织上下文限制业务数据。
  • 🧭平台入口:开发、运维和平台管理员维护全平台模型。
  • 🧱身份来源:Profile是 CRM 会员关系,不是 staff 身份。
  • 🚫错误后果:缺少唯一会员关系时,合法平台数据被隐藏。

结合无Profile和多Profile场景,我的判断很明确。

左侧不是更严格,而是使用了错误的身份来源。

  • 🎯边界结论:租户上下文只属于租户业务入口。
  • 🧹修复行动:Admin 首页移除会员数量和唯一组织推断。

因此,“自动选择唯一组织”没有增加真正的安全性。

它只是把错误的身份模型放到了错误的入口里。

1.2 四个问题重新确认 Admin 边界

我把这次问题压缩成四个必须先回答的问题。

它们是使用者、入口、数据范围和信任级别。

这四个节点中,哪一个可以等到写完代码以后再补?

答案是一个也不能。

  • 👤使用者:入口服务于开发、运维和平台管理员。
  • 🚪访问入口:使用原生/admin/,不是租户 CRM 工作台。
  • 🌐数据范围:默认查看全平台,人可以主动筛选组织。
  • 🛡️信任级别:Django staff 和模型权限定义平台信任。

我在返工中最明确的体会是,四问不是一份文档模板。

它是动手前的架构闸门。

  • 🧠判断顺序:先完成边界分类,再讨论查询和布局。
  • 🛑停止条件:答案不清楚时停止实现,不允许静默补全。

答案确定后,很多争论自然结束了。

Admin 不从Profilerequest.org、JWT 或 API Key 推断租户。

它也不把跨组织指标伪装成某个组织的经营看板。

二、在三种后台边界方案中做选择

边界明确以后,才有资格比较具体方案。

2.1 单租户 Admin、平台 Admin 和物理拆分

围绕 Django Admin,我评估了三种方案。

三张卡片真正比较的是什么?

它们比较的是入口、数据范围和维护成本如何组合。

  • 🏢单租户 Admin:登录后绑定一个组织,只显示组织数据。
  • 🗺️平台 Admin:沿用/admin/,全平台数据显式展示组织。
  • 🧩物理拆分:新建平台入口和注册白名单,形成强隔离。

当前只有内部人员使用 Admin,也不计划建设第二套后台。

因此我选择中间方案,而不是把“隔离最强”当成“当前最好”。

  • 🟢当前选择:将 Django Admin 定义为内部平台控制台。
  • 重选条件:租户管理员进入 Admin 时重新做架构决策。

单租户方案适合租户管理员直接使用 Admin 的产品。

这不是当前如意 CRM 的使用方式。

物理拆分边界最强,但超出了本次 Admin 优化范围。

2.2 为什么当前选择内部平台 Admin

最终选择保留/admin/,由 Django 权限控制平台操作。

这符合 Django 官方对 Admin 的定位。

官方将其描述为可信用户使用的、以模型为中心的内部管理工具。

当需求转向业务流程界面时,应编写自己的视图。

不应该把整个业务前端建立在 Admin 上。

https://docs.djangoproject.com/en/6.0/ref/contrib/admin/

  • ⚙️原生能力:保留模型权限、CSRF、审计日志和成熟表单。
  • 📌范围标签:首页明确标注“全平台数据”。
  • 🔎主动筛选:管理员选择组织筛选,不被系统静默绑定。
  • 🪶改造半径:使用浅层AdminSiteModelAdmin扩展。

这不是说多租户不重要。

而是把多租户控制放回正确的位置。

业务 API 与 PostgreSQL RLS 继续保护租户数据。

Django Admin 承担受信平台人员的内部治理任务。

三、把架构决策写进源码

文字定义边界以后,源码必须执行同一个答案。

3.1RuyiAdminSite不再推断当前组织

RuyiAdminSite.index()只构造平台首页上下文。

它不读取管理员的 CRM 会员关系。

defindex(self,request,extra_context=None):context={**(extra_contextor{})}context["ruyi_dashboard"]=build_admin_dashboard(request,self)returnsuper().index(request,extra_context=context)

仪表盘依据 Django 模型权限决定指标和快捷入口是否可见。

统计查询本身面向全平台。

  • 📊查看权限:指标根据对应的view_model权限显示。
  • 新增权限:快捷入口根据对应的add_model权限显示。
  • 🏷️范围声明:首页固定展示“全平台数据”标签。
  • 🔐入口保护:非 staff 用户仍由原生 Admin 拒绝。

无会员关系、单会员关系和多会员关系不会产生三套 Admin 语义。

这正是平台边界稳定后的直接结果。

3.2 组织归属必须显式可见

平台范围不等于忽略组织归属。

管理员能跨组织操作时,org更应该成为显式信息。

判断节点分出的三条路径说明了什么?

组织信息要同时覆盖查看、筛选和写入。

  • 👁️组织列:查看记录时立即识别它属于哪个组织。
  • 🔦组织筛选:排查问题时主动缩小到指定组织。
  • 🖊️组织表单:新增记录时明确选择记录归属。

我选择在RuyiAdminSite.register()阶段统一增强。

它覆盖所有已注册且含org字段的模型,又不侵入业务查询。

  • 🧷实现结论:组织归属显式可见,但不自动过滤数据。
  • 🧯例外规则:特殊模型必须记录理由并补充精确测试。

PlatformOrgAdminMixin补充组织列、筛选器和表单字段。

它不修改查询集,也不自动填入某个组织。

defget_list_display(self,request):display=tuple(super().get_list_display(request))returndisplayif"org"indisplayelse(*display,"org")

Django 官方把ModelAdmin定义为模型在管理界面中的表示。

它提供列表、筛选器和表单字段等扩展点。

https://docs.djangoproject.com/en/6.0/ref/contrib/admin/#modeladmin-objects

  • 🧾查看合同:所属组织始终进入模型列表信息。
  • 🎛️检索合同:组织始终成为平台管理员的筛选维度。
  • ✍️写入合同:新增和编辑表单必须暴露组织字段。
  • 🧲统一注册:通用混入避免业务应用逐个遗漏组织信息。

四、让一次修复变成长期边界

源码可以修复当前问题,但不能独自约束未来行为。

4.1 为什么只改源码还不够

项目过去没有清晰规则说明 Admin 不是租户工作台。

如果只删除一次查询,同样的推断仍可能在下一次优化中回来。

因此,我把决策落到了五个层次。

闭环里最关键的是哪一个节点?

关键不是单点,而是测试能否重新连接到最初的架构理由。

  • 📜架构决策:记录选择理由、影响范围和重新决策条件。
  • 🤖行为规范:AGENTS.md在 Admin 改动前设置四问闸门。
  • 🧰专用技能:ruyi-admin-boundary给出禁区和验收命令。
  • 🧬源码约束:统一AdminSite与混入类执行平台边界。
  • 自动测试:无会员、多会员和组织字段合同阻止回归。

我不再把“已经解释过”当成长期保障。

只有决策可执行、执行可验证,边界才真正进入项目。

  • 🔁治理结论:规范、源码和测试必须首尾相接。
  • 📍后续行动:每次 Admin 改动从四问开始,以测试结束。

文档解释“为什么”,规范约束“开始之前”。

源码执行“现在”,测试阻止“以后退回去”。

4.2 验收结果和适用边界

本次聚焦测试共通过 16 项。

迁移漂移检查没有发现新迁移。

文档治理检查和差异检查也通过。

  • 🧪无会员场景:Profile的超级管理员可使用平台首页。
  • 🔄多会员场景:多组织会员关系不会隐藏或改变指标。
  • 🌍跨组织统计:两个组织的数据进入全平台指标。
  • 非 staff 场景:普通登录用户不能进入 Django Admin。
  • 🗂️组织字段合同:org的模型暴露列、筛选和表单。
  • 🌏三语言行为:简体中文、繁体中文和英语测试继续通过。

这些结果证明 Admin 平台边界和组织显式化合同成立。

它们不代表业务端租户隔离的全部安全性已经被重新验收。

这次没有扩展 SvelteKit、Flutter、业务 API 或 PostgreSQL RLS。

也没有把桌面端和移动端业务验收混入 Django Admin 范围。

边界修复既要知道必须改什么,也要知道不该顺手改什么。

如果未来租户管理员真的需要使用 Django Admin,

项目应新建架构决策,设计独立入口、组织选择和权限模型。

不能在当前平台 Admin 中恢复自动租户推断。

这次复盘留下的原则很简单:多租户入口都要有数据边界。

但边界不能靠猜。

先确认使用者、入口、数据范围和信任级别,

再让代码执行这个答案。

http://www.jsqmd.com/news/1334260/

相关文章:

  • 营销数据如何驱动业务增长?拆解五个被忽视的关键指标
  • 2026重庆北碚渝北巴南虫害防治PCO技术优势全解析 - LYL仔仔
  • Android手机免Root运行原生Ubuntu桌面:Termux+PRoot实战指南
  • 计算机考研408数据结构代码题突破指南:从理论到实战的完整解决方案
  • 虚幻引擎TScriptInterface:解决蓝图与C++接口传递的类型安全问题
  • 拯救者BIOS隐藏选项解锁:3步轻松掌握联想笔记本性能调校完整指南
  • 信工所考研复试经验复盘:流程解析、高频问题与线上实战指南
  • 2026年抖音企业号运营服务商五维评测:垂直B端赛道头部玩家解析 - 行业评论官xj
  • Windows和Office智能激活终极指南:KMS_VL_ALL_AIO完整解析
  • 3分钟快速上手:使用XUnity.AutoTranslator让外文游戏秒变中文版
  • 行业内热门的国产存储芯片测试座厂商整套解决方案
  • 智能体系统部署与运维实战指南
  • 2026广州装修公司深度测评|实地走访+工地核验+业主回访优选清单 - 装修新知
  • 营销数据怎么做分析?从零搭建全渠道营销数据看板的完整指南
  • 从A股极限操作到技术风控:构建数据驱动的系统决策框架
  • Python爬虫实战:从零构建合法、稳健的数据采集系统
  • 重音teto音源从零使用指南:UTAU/CeVIO/Synthesizer V全平台调校教程
  • NGA论坛优化脚本终极指南:快速打造个性化浏览体验
  • 3分钟快速上手videocr:Python视频字幕提取终极指南
  • 工业视觉与深度学习在PCB缺陷检测中的应用实践
  • 长沙企业 GEO 项目实施拆解:即搜 AI 技术落地实操复盘 - 商业观察
  • 2026惠州儿童舞蹈学习测评:漫亦晨星如何把芭蕾舞基础和中国舞表达结合起来 - 兔兔不是荼荼
  • 多维度拆解小程序平台:数字化经营工具的理性选择指南
  • 洛阳门窗厂家怎么选?除了看样品间,先看生产能力、施工流程和售后边界 - 中国远见品牌企业资讯
  • AI生成趋势报告实战手册(从数据喂养到高管采纳的完整链路)
  • AMD锐龙SDT调试工具:Ryzen处理器性能调优终极指南
  • 芯片低功耗设计实战:时钟门控原理、实现与调试全解析
  • Unity游戏集成Steam成就与多语言支持的完整实战指南
  • Tyto高级技巧:利用Markdown和链接功能提升任务管理效率
  • 3分钟快速上手HIS医院信息系统:从零部署到专业应用完整指南