如何利用eea.facetednavigation查询Dexterity类型的关联项?
我之前也碰到过几乎一模一样的场景,核心矛盾就是eea.facetednavigation默认依赖的related_to索引是为Archetypes(AT)设计的,而Dexterity的plone.app.relationfield根本不会往这个索引里写入数据。下面给你几个可行的解决方案,按从易到难排序:
方案1:给Dexterity对象添加getRawRelated索引器
这个思路相当于“兼容旧索引”,让Dexterity的关联项也能填充到AT风格的related_to索引里,这样eea.facetednavigation完全不用修改就能直接用。
你可以通过plone.indexer注册一个自定义索引器,针对实现了IRelatedItems行为的Dexterity对象,提取关联项的UID列表:
from plone.indexer import indexer from plone.app.relationfield.behavior import IRelatedItems from zope.component import adapter @adapter(IRelatedItems) @indexer(IRelatedItems) def getRawRelatedIndexer(obj): # 获取关联项的RelationValue列表 related_items = obj.relatedItems # 提取每个有效关联项的UID(过滤掉已删除的对象) return [item.to_object.UID() for item in related_items if item.to_object is not None]
把这段代码放到你的产品的indexers.py文件里,然后在configure.zcml中注册这个索引器:
<adapter factory=".indexers.getRawRelatedIndexer" name="getRawRelated" />
完成后去Plone的维护页面执行“重新编目”操作,这样Dexterity对象的关联项就会被写入related_to索引,eea.faceted的关联筛选就能正常工作了。
方案2:配置eea.facetednavigation使用Dexterity原生关联索引
如果不想依赖AT的旧索引,你可以直接让eea.faceted查询Dexterity自带的关联索引。plone.app.relationfield会给实现IRelatedItems的对象自动创建一个relatedItems索引,类型是RelationValue。
操作步骤很简单:
- 进入你的faceted页面的配置界面
- 点击“添加筛选器”,选择“关联”类别的筛选器(或者手动选择索引)
- 在索引选择下拉框里找到
relatedItems(而不是原来的related_to) - 配置筛选器的显示名称、多选模式等参数即可
这种方案不需要写代码,但需要确认你的eea.facetednavigation版本支持查询RelationValue类型的索引。如果版本较旧,可能需要先升级到新版。
方案3:利用eea.relations的统一索引适配
你提到已经试过eea.relations,其实这个包的核心作用就是统一处理AT和Dexterity的关联关系,并且会创建专门的关联索引(比如eea_related_to)。如果之前没生效,大概率是没用到它的专属索引:
- 确保
eea.relations已经正确安装并激活,并且运行过它的安装步骤(会自动创建专属索引) - 进入eea.facetednavigation的配置界面,添加新筛选器时选择
eea.relations提供的eea_related_to索引 - 配置筛选器的显示和查询参数,最后保存配置
之后重新编目所有对象,这个筛选器就能同时查询AT和Dexterity的关联项了。
内容的提问来源于stack exchange,提问作者CMcStone

