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文档。我可以想到至少有两种方法可以实现:
-
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 /实现细节的一部分,可能会在将来的版本中更改)
-
Have each of your documents implement a
as_dict
method which returns a dictionary representation of the object. This would work similarly to theto_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文档。我可以想到至少有两种方法可以实现:
-
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 /实现细节的一部分,可能会在将来的版本中更改)
-
Have each of your documents implement a
as_dict
method which returns a dictionary representation of the object. This would work similarly to theto_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)