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

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

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

问题

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

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

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

我发送的OrderedDicts之一的示例:

  1. { 'foods': {
  2. 3: ['apple', 5],
  3. 1: ['banana', 7],
  4. 2: ['carrot', 3]
  5. },
  6. 'animals': {
  7. 5: ['cat', 3],
  8. 3: ['dog', 10],
  9. 1: ['pig', 5],
  10. }
  11. }

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

  1. { 'foods': {
  2. 1: ['banana', 7],
  3. 2: ['carrot', 3],
  4. 3: ['apple', 5],
  5. },
  6. 'animals': {
  7. 1: ['pig', 5],
  8. 3: ['dog', 10],
  9. 5: ['cat', 3],
  10. }
  11. }

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

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

  1. class DashboardType(g.ObjectType):
  2. data = GenericScalar()
  3. class Query(object):
  4. dashboard = Field(DashboardDataType, id=ID(), date=Date())
  5. def resolve_dashboard(self, info, **kwargs):
  6. data = function_to_get_the_data(kwargs)
  7. # 到这一步为止,数据仍然按预期排序
  8. 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 -->

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

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

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

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 -->

  1. class DashboardType(g.ObjectType):
  2. data = GenericScalar()
  3. class Query(object):
  4. dashboard = Field(DashboardDataType, id=ID(), date=Date())
  5. def resolve_dashboard(self, info, **kwargs):
  6. data = function_to_get_the_data(kwargs)
  7. # up until this point the data is still sorted correctly
  8. 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

  1. 我建议一个模型:
  2. ```graphql
  3. type 东西 {
  4. id: ID!
  5. 名字: String!
  6. 子东西: [子东西]
  7. }
  8. type 子东西 {
  9. id: ID!
  10. 名字: String!
  11. 数量: Int
  12. }

然后你可以有一个查询:

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

然后你可以执行:

  1. 查询 按名字获取东西($按顺序: '名字', $方向: '升序') {
  2. 查询 获取东西(按顺序: $按顺序, 方向: $方向) {
  3. id
  4. 名字
  5. 子东西 {
  6. id
  7. 名字
  8. 数量
  9. }
  10. }
  11. }

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

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

  1. [
  2. {
  3. "id": `ID`,
  4. "名字": "食物",
  5. "子东西": [
  6. {
  7. "id": 3,
  8. "名字": "苹果",
  9. "数量": 5
  10. },
  11. 等等…
  12. ]
  13. }
  14. ]
英文:

I would suggest as a model:

  1. type Thing {
  2. id: ID!
  3. name: String!
  4. subthings: [Subthing]
  5. }
  6. type Subthing {
  7. id: ID!
  8. name: String!
  9. amount: Int
  10. }

Then you could have a guery:

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

And against that you could execute:

  1. query getThingsOrderByName($orderBy: &#39;name&#39;, $direction: &#39;asc&#39;) {
  2. query getThings(orderBy: $orderBy, direction: $direction) {
  3. id
  4. name
  5. subthings {
  6. id
  7. name
  8. amount
  9. }
  10. }
  11. }

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

Your return object would then look like:

  1. [
  2. {
  3. &quot;id&quot;: `
  4. &quot;name&quot;: &quot;foods&quot;
  5. &quot;subthings&quot;: [
  6. {
  7. &quot;id&quot;: 3,
  8. &quot;name&quot;: &quot;apple&quot;,
  9. &quot;amount&quot;: 5,
  10. },
  11. etc…
  12. ]
  13. }
  14. ]

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:

确定