如何在Strapi中实现某一内容类型自动包含另一内容类型的全部条目
实现方案
完全可以实现,不需要手动维护两个内容类型的关联关系,根据你的使用场景可以选择以下两种方案:
方案1:自定义接口返回逻辑(无需调整内容模型,推荐优先使用)
如果你只需要前端调用Plan接口时自动返回全量Dish数据,不需要在Strapi管理后台看到关联关系,直接修改Plan的控制器逻辑即可,不需要设置两个模型的关联字段:
- 打开路径为
src/api/plan/controllers/plan.js的控制器文件 - 改写默认的列表查询和单条查询逻辑,在返回Plan数据的同时拼接全量Dish数据
- 参考代码:
'use strict'; module.exports = { // 重写Plan列表查询接口 async find(ctx) { const { data: plans, meta } = await super.find(ctx); // 拉取全量Dish数据 const allDishes = await strapi.entityService.findMany('api::dish.dish', { publicationState: 'live', // 只返回已发布的Dish,不需要可以去掉 }); // 给每个Plan拼接dishes字段 plans.forEach(plan => { plan.attributes.dishes = allDishes; }); return { data: plans, meta }; }, // 重写Plan单条查询接口 async findOne(ctx) { const { data: plan, meta } = await super.findOne(ctx); const allDishes = await strapi.entityService.findMany('api::dish.dish', { publicationState: 'live', }); plan.attributes.dishes = allDishes; return { data: plan, meta }; } };
这个方案后续新增、删除、修改Dish都会自动同步到所有Plan的返回结果中,不需要额外维护关联关系。
方案2:生命周期钩子自动同步关联(适合需要在后台查看关联数据的场景)
如果你需要在Strapi内容管理后台的Plan详情页也能直观看到所有关联的Dish,可以保留双向多对多关联配置,通过内容类型的生命周期钩子自动完成关联绑定:
- 首先确认两个内容类型已配置双向多对多关联:Plan模型有
dishes关联字段,Dish模型有plans关联字段 - 给Dish模型添加创建后生命周期钩子,新增Dish时自动绑定到所有已有的Plan
- 给Plan模型添加创建后生命周期钩子,新增Plan时自动绑定所有已有的Dish
Dish生命周期参考代码(路径:src/api/dish/content-types/dish/lifecycles.js):
module.exports = { async afterCreate(event) { const { result: newDish } = event; // 拉取所有已创建的Plan ID const allPlans = await strapi.entityService.findMany('api::plan.plan', { fields: ['id'] }); const planIdList = allPlans.map(item => item.id); // 把新Dish关联到所有Plan await strapi.entityService.update('api::dish.dish', newDish.id, { data: { plans: planIdList } }); } };
Plan生命周期参考代码(路径:src/api/plan/content-types/plan/lifecycles.js):
module.exports = { async afterCreate(event) { const { result: newPlan } = event; // 拉取所有已创建的Dish ID const allDishes = await strapi.entityService.findMany('api::dish.dish', { fields: ['id'] }); const dishIdList = allDishes.map(item => item.id); // 把所有Dish关联到新Plan await strapi.entityService.update('api::plan.plan', newPlan.id, { data: { dishes: dishIdList } }); } };
如果需要支持删除Dish/Plan时自动同步解除关联,只需要对应补充afterDelete生命周期逻辑即可。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

