如何仅返回Strapi中选定的某些字段?

时间:2016-07-28 22:29:58

标签: strapi

非常简单(我希望)。我希望能够使用API​​端点并让它只返回指定的字段。 I.E.像这样的东西

[{"name": "Ref1"}]

理想情况下会返回

形式的内容
[
{
"contributors": [
{
"username": "aduensing",
"email": "standin@gmail.com",
"lang": "en_US",
"template": "default",
"id_ref": "1",
"provider": "local",
"id": 1,
"createdAt": "2016-07-28T19:39:09.349Z",
"updatedAt": "2016-07-28T19:39:09.360Z"
}
],
"createdBy": {
"username": "aduensing",
"email": "standin@gmail.com",
"lang": "en_US",
"template": "default",
"id_ref": "1",
"provider": "local",
"id": 1,
"createdAt": "2016-07-28T19:39:09.349Z",
"updatedAt": "2016-07-28T19:39:09.360Z"
},
"updatedBy": {
"username": "aduensing",
"email": "standin@gmail.com",
"lang": "en_US",
"template": "default",
"id_ref": "1",
"provider": "local",
"id": 1,
"createdAt": "2016-07-28T19:39:09.349Z",
"updatedAt": "2016-07-28T19:39:09.360Z"
},
"question": {
"createdBy": 1,
"createdAt": "2016-07-28T19:41:33.152Z",
"template": "default",
"lang": "en_US",
"name": "My Question",
"content": "Cool stuff, huh?",
"updatedBy": 1,
"updatedAt": "2016-07-28T19:45:02.893Z",
"id": "579a5ff83af4445c179bd8a9"
},
"createdAt": "2016-07-28T19:44:31.516Z",
"template": "default",
"lang": "en_US",
"name": "Ref1",
"link": "Google",
"priority": 1,
"updatedAt": "2016-07-28T19:45:02.952Z",
"id": "579a60ab5c8592c01f946cb5"
}
]

不幸的是情况并非如此,实际上它会返回以下内容。



expressoes




如果我决定一次加载10个,20个,30个或更多记录,那么这在任何现实环境中都会立即出现问题,我最终会加载50倍于我需要的数据。更多带宽用完,加载时间更慢等等。

10 个答案:

答案 0 :(得分:3)

我如何解决这个问题:

  1. 创建自定义控制器操作(例如,'findPaths') 在contributor / controllers / contributor.js中
    module.exports = {
       findPaths: async ctx => {
           const result = await strapi
               .query('contributor')
               .model.fetchAll({ columns: ['slug'] }) // here we wait for one column only
           ctx.send(result);
       }
    }
  1. 添加自定义路线(例如“路径”) 在contributor / config / routes.json中
    {
      "method": "GET",
      "path": "/contributors/paths",
      "handler": "contributor.findPaths",
      "config": {
        "policies": []
      }
    },
  1. 在管理面板中为贡献者实体,路径操作添加权限

就是这样。现在,它仅显示所有贡献者记录中的slug字段。

http://your-host:1337/contributors/paths

答案 1 :(得分:3)

您可以通过以下方式返回特定字段并排除关系以优化响应。

  async list (ctx) {
    const result = await strapi.query('article').model.query(qb => {
          qb.select('id', 'title', 'link', 'content');
      }).fetchAll({
          withRelated: []
      }).catch(e => {
          console.error(e)
      });

    if(result) {
        ctx.send(result);
    } else {
        ctx.send({"statusCode": 404, "error": "Not Found", "message": "Not Found"});
    }
  }

答案 2 :(得分:0)

此功能尚未在Strapi中实施。为了补偿,最好的选择可能是使用GraphQL(http://strapi.io/documentation/graphql)。

随意创建问题或提交拉取请求:https://github.com/wistityhq/strapi

答案 3 :(得分:0)

我知道这是旧线程,但我遇到了完全相同的问题,找不到任何解决方案。文档或其他任何地方都没有。

几分钟的控制台日志记录和使用服务后,我能够使用以下代码过滤字段:

const q = Post
  .find()
  .sort(filters.sort)
  .skip(filters.start)
  .limit(filters.limit)
  .populate(populate);

return filterFields(q, ['title', 'content']);

其中filterFields具有以下功能:

function filterFields(q, fields) {
  q._fields = fields;
  return q;
}

这是一个肮脏的解决方案,我还没有弄清楚如何将此方法应用于包含的关系实体,但是我希望它可以帮助某人寻找该问题的解决方案。

我不确定为什么trapdi不支持此操作,因为当显式设置字段时,它显然能够过滤字段。像这样使用它会很好:

return Post
      .find()
      .fields(['title', 'content'])
      .sort(filters.sort)
      .skip(filters.start)
      .limit(filters.limit)
      .populate(populate);

答案 4 :(得分:0)

如果使用的是MongoDB数据库,则可以使用select函数:
等待stripi.query('game-category')。model.find()。select([“ Code”])
如您所见,我有一个名为game-category的模型,我只需要“代码”字段,所以我使用了Select函数。

答案 5 :(得分:0)

在当前的bandi版本(3.x,不确定以前的版本)中,无论使用哪个ORM,都可以使用custom queries中的select方法来实现。

SQL示例:

 const restaurant = await strapi
    .query('restaurant')
    .model.query((qb) => {
        qb.where('id', 1);
        qb.select('name');
    })
    .fetch();

答案 6 :(得分:0)

不是很漂亮,但是你可以在回来之前删除它。

参考这里: https://strapi.io/documentation/developer-docs/latest/guides/custom-data-response.html#apply-our-changes

ThenInclude()

答案 7 :(得分:0)

是的,我记得另一种方式。 您可以使用 xx.settings.json 文件中的属性。

参考: model-options

{
  "options": {
    "timestamps": true,
    "privateAttributes": ["id", "created_at"],   <-this is fields you dont want to return
    "populateCreatorFields": true    <- this is the system fields,set false to not return
  }
}

答案 8 :(得分:0)

您可以覆盖以下默认的 Strapi 实体响应:-

entity = await strapi.services.weeklyplans.create(add_plan);

return sanitizeEntity(entity, { model: strapi.models.weeklyplans });

通过使用:-

ctx.response.body = { 
              status: "your API status", 
              message: "Your own message" 
        }

使用 ctx 对象,我们可以选择我们想要显示为对象的字段。 并且不需要返回任何东西。将 ctx.response.body 放置在满足条件时必须发送响应的位置。

答案 9 :(得分:0)

最好让查询选择字段,而不是依靠节点来删除内容。但是,我发现这在某些情况下很有用,并认为我会分享。 strapi sanitizeEntity 函数可以包含额外的选项,其中之一允许您只包含您需要的字段。类似于手动删除字段但更可重用的功能。

const { sanitizeEntity } = require('strapi-utils');

let entities = await strapi.query('posts').find({ parent: parent.id })

return entities.map(entity => {
  return sanitizeEntity(entity, {
    model: strapi.models['posts'],
    includeFields: ['id', 'name', 'title', 'type', 'parent', 'userType']
  });
});