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

发布于 2024-11-10 04:01:44 字数 1092 浏览 3 评论 0原文

所以我试图返回一个项目的 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 有什么想法吗?

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.

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

暮倦 2024-11-17 04:01:44

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

>>> User.objects.to_json()

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

>>> User.objects.to_json()
不喜欢何必死缠烂打 2024-11-17 04:01:44

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

最终,您的 default 函数需要能够有意义MongoEngine 文档。我可以想到至少有两种方法可以实现这一点:

  1. 编写一个自定义的 default 函数,通过内省其 _fields 属性来适用于所有 MongoEngine 文档(尽管注意前导下划线意味着这是 MongoEngine 的私有 API/实现细节的一部分,并且在未来版本中可能会发生变化)

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

我建议您使用选项#2:代码会更干净、更容易阅读、封装得更好,并且不需要使用任何私有 API。

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.)

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:

  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)

  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).

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.

却一份温柔 2024-11-17 04:01:44

正如 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)

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

Document definition

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文