如何避免Graphene在查询响应时对OrderedDict进行排序?(Python,Django)

huangapple go评论119阅读模式
英文:

How to avoid Graphene sorting an OrderedDict on query response? (Python, Django)

问题

我试图从Django应用程序中的Graphene端点返回一个OrderedDict的字典,使用了GenericScalar类型字段。

OrderedDict根据值排序,但API似乎重新按键对字典进行排序。

OrderedDict的项目格式为:{ id : [name, amount] }

我发送的OrderedDicts之一的示例:

{ 'foods': {
    3: ['apple', 5],
    1: ['banana', 7],
    2: ['carrot', 3]
  }, 
  'animals': {
    5: ['cat', 3],
    3: ['dog', 10],
    1: ['pig', 5],
  }
}

在端点响应中收到的内容:

{ 'foods': {
    1: ['banana', 7],
    2: ['carrot', 3],
    3: ['apple', 5],
  }, 
  'animals': {
    1: ['pig', 5],
    3: ['dog', 10],
    5: ['cat', 3],
  }
}

我特别使用OrderedDicts,因为顺序很重要,但我找不到一种方法来避免Graphene按键重新排序OrderedDicts。

这是ObjectType和Query的声明方式,尽管没有什么特别之处:

class DashboardType(g.ObjectType):
    data = GenericScalar()

class Query(object):
    dashboard = Field(DashboardDataType, id=ID(), date=Date())
   
    def resolve_dashboard(self, info, **kwargs):
        data = function_to_get_the_data(kwargs)
        # 到这一步为止,数据仍然按预期排序
        return data

数据按预期排序,直到Graphene API发送响应。我期望顺序能够保持,但实际情况并非如此。

有关如何实现此目标的建议吗?
我没想到会这么困难,但我已经没有主意了。

英文:

I am trying to return a dict of OrderedDicts from a Graphene endpoint in a Django application, by using the GenericScalar type field.
The OrderedDicts are sorted based on value, but the API seems to re-sort the dicts by key.

The OrderedDicts items format is: { id : [name, amount] }

Example of one of the OrderedDicts that I send:
<!-- language: python -->

{ &#39;foods&#39;: {
    3: [&#39;apple&#39;, 5],
    1: [&#39;banana&#39;, 7],
    2: [&#39;carrot&#39;, 3]
  }, 
  &#39;animals&#39;: {
    5: [&#39;cat&#39;, 3],
    3: [&#39;dog&#39;, 10],
    1: [&#39;pig&#39;, 5],
  }
}

What is received in the endpoint response:
<!-- language: python -->

{ &#39;foods&#39;: {
    1: [&#39;banana&#39;, 7],
    2: [&#39;carrot&#39;, 3],
    3: [&#39;apple&#39;, 5],
  }, 
  &#39;animals&#39;: {
    1: [&#39;pig&#39;, 5],
    3: [&#39;dog&#39;, 10],
    5: [&#39;cat&#39;, 3],
  }
}

I am specifically using OrderedDicts because the order is important, but I have not found a way of avoiding Graphene to re-sort the OrderedDicts by key.

This is the how the ObjectType and Query are declared, althought is is nothing out of the ordinary.
<!-- language: python -->

class DashboardType(g.ObjectType):
    data = GenericScalar()

class Query(object):
    dashboard = Field(DashboardDataType, id=ID(), date=Date())
   
    def resolve_dashboard(self, info, **kwargs):
        data = function_to_get_the_data(kwargs)
        # up until this point the data is still sorted correctly
        return data

The data is sorted as expected up until the response is sent by the Graphene API. I would expect the order to be mantained, but it is not.

Any suggestions on how to achieve this?
I didn't think it would be so difficult, but I am out of ideas.

答案1

得分: 0

我建议一个模型:

```graphql
type 东西 {
  id: ID!
  名字: String!
  子东西: [子东西]
}

type 子东西 {
  id: ID!
  名字: String!
  数量: Int
}

然后你可以有一个查询:

查询 获取东西(按顺序: String, 方向: String): [东西]

然后你可以执行:

查询 按名字获取东西($按顺序: '名字', $方向: '升序') {
  查询 获取东西(按顺序: $按顺序, 方向: $方向) {
    id
    名字
    子东西 {
      id
      名字
      数量
    }
  }
}

然后你的 子东西 解析器可以根据 按顺序方向 查询参数对 子东西 进行排序。

然后你的返回对象将如下所示:

[
  {
    "id": `ID`,
    "名字": "食物",
    "子东西": [
      {
        "id": 3,
        "名字": "苹果",
        "数量": 5
      },
      等等…
    ]
  }
]
英文:

I would suggest as a model:

type Thing {
  id: ID!
  name: String!
  subthings: [Subthing]
}

type Subthing {
  id: ID!
  name: String!
  amount: Int
}

Then you could have a guery:

query getThings(orderBy: String, direction: String): [Thing]

And against that you could execute:

query getThingsOrderByName($orderBy: &#39;name&#39;, $direction: &#39;asc&#39;) {
  query getThings(orderBy: $orderBy, direction: $direction) {
    id
    name
    subthings {
      id
      name
      amount
    }
  }
}

Your subThings resolver could then sort the subThings based on the orderBy and 'direction' query parameters.

Your return object would then look like:

[
  {
    &quot;id&quot;: `
    &quot;name&quot;: &quot;foods&quot;
    &quot;subthings&quot;: [
      {
        &quot;id&quot;: 3,
        &quot;name&quot;: &quot;apple&quot;,
        &quot;amount&quot;: 5,
      },
      etc…
    ]
  }
]

huangapple
  • 本文由 发表于 2023年7月13日 23:58:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76681328.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定