先说结论
Odoo 网站里的 Customers 页面,不是“后台勾几个客户,然后前台摆一排 Logo”这么简单。
website_customer 真正构建的是一个公开案例目录,它同时处理:
- 哪些客户允许公开展示;
- 如何按行业、国家、标签进行筛选;
- 列表页怎样统计各筛选分组数量;
- 有没有 Google Maps 地图视图;
- 详情页该如何在 slug 与公开边界内安全访问。
所以这个模块更像一个轻量版的“客户案例库”,而不是纯装修组件。
一、为什么 Customers 页面从一开始就不是随便公开联系人
controller 里的基础 domain 很明确:
website_published = Trueassigned_partner_id != False
这两个条件合起来很重要。
第一层说明:
- 不是所有联系人都能上官网,必须显式发布。
第二层说明:
- 只有被视作“客户案例 / 客户引用对象”的伙伴,才应该出现在目录里;
- 普通联系人、供应商、内部地址记录,并不会自动挤进前台。
也就是说,Odoo 在产品层面已经把“CRM/联系人数据库”和“公开客户案例库”划了一道线。
二、为什么列表筛选按行业和国家做聚合,而不是前端死写选项
customers() 里会先基于当前搜索 domain 做两次 _read_group():
- 一次按
industry_id - 一次按
country_id
然后把统计结果转换成前台可渲染的筛选数据。
这代表一个很务实的思路:
筛选项应该从当前真实可展示的数据里长出来。
好处有三个:
- 没有客户的行业不会硬占位置;
- 搜索后筛选计数仍然可信;
- 前台不需要维护一套和数据库可能脱节的静态选项。
所以这不是“多加几个下拉框”的事,而是案例目录的可维护性设计。
三、为什么 country 命中过空时要自动回退到 All Countries
源码里有个细节很容易被忽略:
- 如果当前 country 路由存在;
- 但在现有结果里这个国家已经没有客户;
- 系统会把
fallback_all_countries = True,并把当前国家置空。
这个体验非常像成熟目录站,而不是死板后台页。
因为现实里常会发生:
- 某客户取消公开;
- 案例被下线;
- 搜索词变化导致该国家下没有结果。
如果系统强行留在一个空国家筛选里,用户会以为网站坏了。
Odoo 的处理更聪明:
- 路由可以保留;
- 但结果层面回退到“所有国家”;
- 同时告诉前台这是一次 fallback。
四、为什么标签不是联系人标签,而是“网站标签”
res.partner 在这里扩展的是:
website_tag_ids
而不是直接拿 CRM 里所有伙伴标签来复用。
同时 res.partner.tag 在这个模块里被定义成:
- 可发布;
- 带颜色 class;
- 专门用于网站筛选客户案例。
这说明 Odoo 非常清楚后台业务标签和前台公开分类不是一回事。
如果直接把内部标签全端出去,前台会很快变成:
- 含义不统一;
- 运营不可控;
- 甚至暴露内部管理语义。
所以它专门给客户案例页留了一套网站标签体系。
五、为什么 Customers 还要兼容地图能力
controller 继承的是 website_google_map.controllers.main.GoogleMap。
并且 _get_gmap_domains() 会在 dom == "website_customer.customers" 时,改写成客户案例页面自己的 domain。
这说明 Odoo 把客户案例目录理解成可以同时存在两种浏览方式:
- 文本列表 / 卡片浏览;
- 地理分布浏览。
对于做国际客户展示、区域覆盖证明、线下服务能力说明的公司来说,这比普通 logo 墙有说服力得多。
也就是说,Customers 页面并不只是内容展示,而是销售可信度的一个证明入口。
六、为什么详情页访问还要校验 slug 和公开状态
/customers/<partner_id> 这条路由不是 semantic route,而是手动 unslug 再检查。
流程大致是:
- 先从 slug 里解出 partner id;
sudo()读取伙伴;- 检查记录是否存在且
website_published=True; - 如果 slug 不规范,则 302 重定向到正确 slug;
- 否则渲染详情页;
- 任一条件不满足就
not_found()。
这说明 Odoo 很重视案例详情页的两个基础问题:
- URL 标准化;
- 非公开记录不能被随便捞出来。
对于官网案例页来说,这一点非常必要。
七、实施时最容易误解的地方
1. 以为 Customers 只是展示组件,不是内容目录
不对。源码明显在做分组、搜索、分页和地图支持。
2. 以为联系人只要存在就能上站
不对。必须同时满足公开发布与客户归属条件。
3. 以为标签可以直接复用后台联系人标签
不对。网站公开标签和内部业务标签最好分开。
4. 以为空国家筛选结果就该硬显示 0 条
不对。更好的体验是回退到 All Countries。
最后总结
Odoo 的 website_customer 真正做的是:
- 把可公开的客户案例从联系人数据库里挑出来;
- 组织成带国家、行业、标签与地图能力的目录;
- 让列表页和详情页都遵守公开展示边界;
- 用更可检索、更可信的方式替代简单 Logo 墙。
所以它更像:
一个为销售可信度服务的官网客户案例目录系统。
DISCUSSION
评论区