7

所以我试图为一个项目返回一个 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 的任何想法?

4

3 回答 3

11

在 MongoEngine 0.8 或更高版本中,对象和查询集有一个to_json()方法。

>>> User.objects.to_json()
于 2013-05-31T07:21:18.187 回答
8

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

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

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

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

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

于 2011-06-08T11:56:04.190 回答
4

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

文档定义

class MyDocument(Document):
    # Your document definition

    def to_dict(self):
        return mongo_to_dict_helper(self)

助手.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)
于 2012-08-30T22:20:19.570 回答