【问题标题】:Simplify MongoEngine QuerySet Results简化 MongoEngine QuerySet 结果
【发布时间】:2021-07-06 18:49:22
【问题描述】:

问题

我有一个以 JSON 格式返回 mongoengine 结果的 API,但前端(在我的范围之外)对该格式不满意,即存在像 {"$oid": "60e4a07097ddf1e20fbaaaa0"} 这样的值。

以下是访问 GET 端点的响应示例:

[
  {
    "name": "Double R Diner",
    "permissions": [
      {
        "user": {
          "$oid": "60de35e078ba4f6f3f41e519"
        },
        "role": {
          "name": "admin",
          "description": "account creator"
        }
      },
      {
        "user": {
          "$oid": "60de35e078ba4f6f3f41e516"
        },
        "role": {
          "name": "admin",
          "description": "Double R Diner admin"
        }
      }
    ],
    "buildings": [
      {
        "$oid": "60de35e078ba4f6f3f41e51e"
      }
    ],
    "address": {
      "country": "United States",
      "province_state": "WA",
      "city": "Twin Peaks"
    },
    "main_contact": {
      "$oid": "60de35e078ba4f6f3f41e519"
    },
    "_id": {
      "$oid": "60de35e078ba4f6f3f41e520"
    }
  }
]

$oid 字段的嵌套是问题所在,因为前端认为这是一个过于复杂的问题,将我们锁定在这个奇怪的 mongoengine 格式标准中。这个嵌套应该被移除,$oid 字符串值尽可能替换它们的嵌套字典。如您所见,嵌套可以发生在字典 (main_contact) 和/或列表 (buildings) 中。

期望的结果如下所示:

[
  {
    "name": "Double R Diner",
    "permissions": [
      {
        "user": "60de35e078ba4f6f3f41e519",
        "role": {
          "name": "admin",
          "description": "account creator"
        }
      },
      {
        "user": "60de35e078ba4f6f3f41e516",
        "role": {
          "name": "admin",
          "description": "Double R Diner admin"
        }
      }
    ],
    "buildings": [
      "60de35e078ba4f6f3f41e51e"
    ],
    "address": {
      "country": "United States",
      "province_state": "WA",
      "city": "Twin Peaks"
    },
    "main_contact": "60de35e078ba4f6f3f41e519",
    "_id": "60de35e078ba4f6f3f41e520"
  }
]

我认为这是一个递归问题,递归让我很头疼。

问题

我怎样才能最好地实现上述转变;简化响应数据结构,让前端不知道 mongoengine $oid dicts,不管这些 ObjectId 嵌套多深?

【问题讨论】:

    标签: python mongoengine


    【解决方案1】:

    我确信有更好的方法可以做到这一点,但我似乎已经通过以下实现解决了这个问题:

    def simplify_ids(obj):
        if type(obj) not in [list, dict]:
            return obj
    
        if type(obj) == dict:
            if len(obj) == 1 and '$oid' in obj.keys():
                obj = obj['$oid']
                return obj
            else:
                for key, value in obj.items():
                    obj[key] = simplify_ids(value)
    
        elif type(obj) == list:
            for index, nested_obj in enumerate(obj):
                obj[index] = simplify_ids(nested_obj)
    
        return obj
    
    
    def clean_query_results(query_results):
        if type(query_results) != QuerySet:
            raise TypeError(f'Input must be a mongoengine QuerySet, not {type(query_results)}')
        result_string = query_results.to_json()
        loaded = json.loads(result_string)  # List
        cleaned = list()
        for obj in loaded:
            cleaned.append(simplify_ids(obj))
        return json.dumps(cleaned)
    

    调用端点只需将响应行更改为:

    return Response(query_results.to_json(), mimetype='application/json', status=200)
    

    到:

    return Response(clean_query_results(query_results), mimetype='application/json', status=200)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-18
      • 2019-09-24
      • 2019-05-04
      • 2018-12-06
      • 1970-01-01
      • 2021-07-09
      • 1970-01-01
      • 2013-02-15
      相关资源
      最近更新 更多