使用MongoEngine Pymongo和Django无法返回JSON对象?

时间:2023-01-11 08:40:36

So I'm trying to return a JSON object for a project. I've spent a few hours trying to get Django just returning the JSON.

所以我试图为项目返回一个JSON对象。我花了几个小时试图让Django返回JSON。

Heres the view that we've been working with:

以下是我们一直在合作的观点:

def json(request, first_name):
    user = User.objects.all()
    #user = User.objects.all().values()
    result = simplejson.dumps(user, default=json_util.default)
    return HttpResponse(result)

Here's my model:

这是我的模特:

class User(Document):  
    gender = StringField( choices=['male', 'female', 'Unknown']) 
    age = IntField()
    email = EmailField()
    display_name = StringField(max_length=50)
    first_name = StringField(max_length=50)
    last_name = StringField(max_length=50)
    location = StringField(max_length=50)
    status = StringField(max_length=50)
    hideStatus = BooleanField()
    photos = ListField(EmbeddedDocumentField('Photo')) 
    profile =ListField(EmbeddedDocumentField('ProfileItem'))
    allProfile = ListField(EmbeddedDocumentField('ProfileItem')) #only return for your own profile

This is what it's returning:

这就是它的回归:

[<User: User object>, <User: User object>] is not JSON serializable

Any thoughts on how I can just return the JSON?

关于如何才能返回JSON的任何想法?

3 个解决方案

#1


10  

With MongoEngine 0.8 or greater, objects and querysets have a to_json() method.

对于MongoEngine 0.8或更高版本,对象和查询集具有to_json()方法。

>>> User.objects.to_json()

#2


8  

simplejson.dumps() doesn't know how to "reach into" your custom objects; the default function, json_util.default must just be calling str() or repr() on your documents. (Is json_util custom code you've written? If so, showing its source here could prove my claim.)

simplejson.dumps()不知道如何“进入”自定义对象;默认函数json_util.default必须只是在文档上调用str()或repr()。 (你写的是json_util自定义代码吗?如果是这样,在这里显示它的来源可以证明我的主张。)

Ultimately, your default function will need to be able to make sense of the MongoEngine documents. I can think of at least two ways that this might be implemented:

最终,您的默认功能需要能够理解MongoEngine文档。我可以想到至少有两种方法可以实现:

  1. Write a custom default function that works for all MongoEngine documents by introspecting their _fields attribute (though note that the leading underscore means that this is part of the private API/implementation detail of MongoEngine and may be subject to change in future versions)

    通过内省其_fields属性编写适用于所有MongoEngine文档的自定义默认函数(但请注意,前导下划线表示这是MongoEngine的私有API /实现细节的一部分,可能会在将来的版本中更改)

  2. Have each of your documents implement a as_dict method which returns a dictionary representation of the object. This would work similarly to the to_mongo method provided on documents by MongoEngine, but shouldn't return the _types or _cls fields (again, these are implementation details of MongoEngine).

    让每个文档实现一个as_dict方法,该方法返回对象的字典表示。这与MongoEngine在文档上提供的to_mongo方法类似,但不应返回_types或_cls字段(同样,这些是MongoEngine的实现细节)。

I'd suggest you go with option #2: the code will be cleaner and easier to read, better encapsulated, and won't require using any private APIs.

我建议你使用选项#2:代码将更清晰,更易于阅读,更好的封装,并且不需要使用任何私有API。

#3


4  

As dcrosta suggested you can do something like this, hope that will help you.

正如dcrosta建议您可以做这样的事情,希望这对您有所帮助。

Document definition

文件定义

class MyDocument(Document):
    # Your document definition

    def to_dict(self):
        return mongo_to_dict_helper(self)

helper.py:

helper.py:

from mongoengine import StringField, ListField, IntField, FloatField

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, data))
        else:
            # You can define your logic for returning elements
    return dict(return_data)

#1


10  

With MongoEngine 0.8 or greater, objects and querysets have a to_json() method.

对于MongoEngine 0.8或更高版本,对象和查询集具有to_json()方法。

>>> User.objects.to_json()

#2


8  

simplejson.dumps() doesn't know how to "reach into" your custom objects; the default function, json_util.default must just be calling str() or repr() on your documents. (Is json_util custom code you've written? If so, showing its source here could prove my claim.)

simplejson.dumps()不知道如何“进入”自定义对象;默认函数json_util.default必须只是在文档上调用str()或repr()。 (你写的是json_util自定义代码吗?如果是这样,在这里显示它的来源可以证明我的主张。)

Ultimately, your default function will need to be able to make sense of the MongoEngine documents. I can think of at least two ways that this might be implemented:

最终,您的默认功能需要能够理解MongoEngine文档。我可以想到至少有两种方法可以实现:

  1. Write a custom default function that works for all MongoEngine documents by introspecting their _fields attribute (though note that the leading underscore means that this is part of the private API/implementation detail of MongoEngine and may be subject to change in future versions)

    通过内省其_fields属性编写适用于所有MongoEngine文档的自定义默认函数(但请注意,前导下划线表示这是MongoEngine的私有API /实现细节的一部分,可能会在将来的版本中更改)

  2. Have each of your documents implement a as_dict method which returns a dictionary representation of the object. This would work similarly to the to_mongo method provided on documents by MongoEngine, but shouldn't return the _types or _cls fields (again, these are implementation details of MongoEngine).

    让每个文档实现一个as_dict方法,该方法返回对象的字典表示。这与MongoEngine在文档上提供的to_mongo方法类似,但不应返回_types或_cls字段(同样,这些是MongoEngine的实现细节)。

I'd suggest you go with option #2: the code will be cleaner and easier to read, better encapsulated, and won't require using any private APIs.

我建议你使用选项#2:代码将更清晰,更易于阅读,更好的封装,并且不需要使用任何私有API。

#3


4  

As dcrosta suggested you can do something like this, hope that will help you.

正如dcrosta建议您可以做这样的事情,希望这对您有所帮助。

Document definition

文件定义

class MyDocument(Document):
    # Your document definition

    def to_dict(self):
        return mongo_to_dict_helper(self)

helper.py:

helper.py:

from mongoengine import StringField, ListField, IntField, FloatField

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, data))
        else:
            # You can define your logic for returning elements
    return dict(return_data)