无法使用带有 Django 的 MongoEngine Pymongo 返回 JSON 对象?

Posted

技术标签:

【中文标题】无法使用带有 Django 的 MongoEngine Pymongo 返回 JSON 对象?【英文标题】:Can't Return JSON object using MongoEngine Pymongo with Django? 【发布时间】:2011-09-03 01:55:03 【问题描述】:

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

这是我们一直在使用的视图:

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)

这是我的模型:

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

这是它返回的内容:

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

关于如何返回 JSON 有什么想法吗?

【问题讨论】:

【参考方案1】:

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

>>> User.objects.to_json()

【讨论】:

【参考方案2】:

simplejson.dumps() 不知道如何“接触”您的自定义对象; default 函数,json_util.default 必须只是在您的文档上调用 str()repr()。 (json_util 是您编写的自定义代码吗?如果是,在此处显示其源代码可以证明我的说法。)

最终,您的 default 函数需要能够理解 MongoEngine 文档。我至少可以想到两种可能的实现方式:

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

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

我建议您使用选项 #2:代码将更简洁、更易于阅读、更好地封装,并且不需要使用任何私有 API。

【讨论】:

【参考方案3】:

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

文档定义

class MyDocument(Document):
    # Your document definition

    def to_dict(self):
        return mongo_to_dict_helper(self)

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)

【讨论】:

以上是关于无法使用带有 Django 的 MongoEngine Pymongo 返回 JSON 对象?的主要内容,如果未能解决你的问题,请参考以下文章

无法使用带有 Django 的 MongoEngine Pymongo 返回 JSON 对象?

Django - 无法使用两个数据库进行测试(带有 gis 扩展的 postgres 和 mongoDB (Djongo)

带有 Django 的 Bootstrap 4 无法正确显示

使用带有 Compressor 的 Boto 的 Django AWS S3 无法压缩 UncompressableFileError

带有 numpy 的 Django,错误:无法导入名称多数组

带有 Django 的 Heroku 上的 Memcached:无法安装 pylibmc / memcacheify