36

我将瓶子框架与 mongoengine 一起使用。我有一个订单模型:

class OrderDetail(Option):
    orderDetailsQty = FloatField()

    def to_dict(self):
        return mongo_to_dict_helper(self)


class Order(Document):
    userName = StringField(required=True)
    orderDate = DateTimeField()
    orderStatus = ListField(EmbeddedDocumentField(Status))
    orderDetails = ListField(EmbeddedDocumentField(OrderDetail))
    orderComments = ListField(EmbeddedDocumentField(Comment))
    isActive = BooleanField()

    def to_dict(self):
        orderObj = mongo_to_dict_helper(self)
        orderDetailList = []
        for orderDetail in orderObj["orderDetails"]:
            orderDetailList.append(orderDetail.__dict__)
        orderObj["OrderDetails"] = orderDetailList
        return (self)

当查询 mongodb 时,我得到一个对象,然后使用以下函数将其转换为 dict:

def mongo_to_dict_helper(obj):
    return_data = []
    for field_name in obj._fields:
        if field_name in ("id",):
            continue
        data = obj._data[field_name]

        if isinstance(obj._fields[field_name], StringField):
            return_data.append((field_name, str(data)))
        elif isinstance(obj._fields[field_name], FloatField):
            return_data.append((field_name, float(data)))
        elif isinstance(obj._fields[field_name], IntField):
            return_data.append((field_name, int(data)))
        elif isinstance(obj._fields[field_name], ListField):
            return_data.append((field_name, int(data)))
        else:
            # You can define your logic for returning elements
            pass
    return dict(return_data)

我在网上找了很久才找到这个功能。后来发现这个函数在将成员定义为 ListField(EmbeddedDocumentField(obj)) 时也失败了。

我还尝试编写一个条件来捕获 EmbeddedDocumentField 的特定情况:

elif isinstance(obj._fields[field_name], EmbeddedDocumentField):
    return_data.append(mongo_to_dict_helper(data))

但这也没有任何好处。

有人有解决这个问题的方法吗?

4

7 回答 7

54

仅使用to_mongo对象的方法将其转换为字典怎么样?

object.to_mongo()
于 2012-11-05T10:47:45.327 回答
32

扩展@alexvassel 和@z0r 的答案,调用.to_mongo()将对象转换为SON 实例。一旦你有了它,你就可以调用它的.to_dict()方法把它转换成字典

例如...(qset是从 mongoengine 返回的查询集,在 eg 之后Posts.objects.all())。

sons = [ob.to_mongo() for ob in qset]
for son in sons:
    print str(son.to_dict())
于 2015-01-09T06:09:10.827 回答
11
import json
json.loads(yourobj.to_json())
于 2015-05-15T16:23:13.223 回答
7

扩展@alexvassel 的答案,to_mongo()方法返回SON object,您可以通过调用其to_dict()方法将其转换为 dict

object.to_mongo().to_dict()
于 2019-11-08T11:12:24.877 回答
1

您可以自定义方法将对象转换为 dict

class Order(Document):
    userName = StringField(required=True)
    orderDate = DateTimeField()
    orderStatus = ListField(EmbeddedDocumentField(Status))
    orderDetails = ListField(EmbeddedDocumentField(OrderDetail))
    orderComments = ListField(EmbeddedDocumentField(Comment))
    isActive = BooleanField()

    def as_dict(self):
        return {
            "user_name": self.userName,
            "order_date": self.orderDate.strftime("%Y-%m-%d %H:%M:%S"),
        }

现在你可以使用 obj.as_dict() 来听写

orders = Order.objects.all()
datas = [each.as_dict() for each in orders]
于 2019-09-10T06:31:21.420 回答
0

结合所有其他答案,

import json
dict = {'data':[json.loads(ob.to_json()) for ob in qset]}
于 2018-06-14T14:43:03.490 回答
0

可以有两种情况。

  1. 当查询返回 CommandCursor 对象时
    **records = list(CursorObject)**

    ex - Class.objects().aggregate({...})
  1. 当查询返回 BaseQuerySet 对象时
   **import json**

   **records = json.loads(BaseQuerySetObject.to_json())**

   ex - Class.objects().filter(..)
于 2021-03-05T06:20:08.307 回答