我正在使用Flask编写API。我为撰写帖子的用户使用了ReferenceField。 API应返回一个JSON对象,其中包含有关帖子的数据和有关用户的数据。
Flask端点:
@app.route("/api/posts")
def posts_index():
posts = Post.objects()
return jsonify({
"posts": json.loads(posts.to_json())
})
数据库模型:
class User(Document):
email = EmailField(required=True, unique=True)
username = StringField(max_length=50, required=True, unique=True)
password = StringField(required=True)
created = DateTimeField(required=True, default=datetime.datetime.now())
class Comment(EmbeddedDocument):
content = StringField(max_length=5000)
user = ReferenceField(User)
created = DateTimeField(required=True, default=datetime.datetime.now())
class Post(Document):
title = StringField(max_length=120, required=True)
user = ReferenceField(User, reverse_delete_rule=CASCADE)
content = StringField(max_length=5000)
comments = ListField(EmbeddedDocumentField(Comment))
created = DateTimeField(required=True, default=datetime.datetime.now())
JSON回复:
{
"posts": [
{
"_id": {
"$oid": "5a5efd1f9ef3161fc64cb95a"
},
"comments": [],
"content": "Lorem Ipsum",
"created": {
"$date": 1516178223018
},
"title": "Hello",
"user": {
"$oid": "5a5d0b9b9ef316220b6d9881"
}
},
{
"_id": {
"$oid": "5a5efd1f9ef3161fc64cb95b"
},
"comments": [],
"content": "Lorem Ipsum Dolor",
"created": {
"$date": 1516178223018
},
"title": "Hello Again",
"user": {
"$oid": "5a5d0b9b9ef316220b6d9881"
}
}
]
}
我想获得json响应,但ReferenceField应该包含有关用户的信息。
答案 0 :(得分:0)
首先,您应该递归遍历所有字段,最后尝试获取其值。我写了一个小函数来做到这一点。
from mongoengine import Document, EmbeddedDocument
from mongoengine.queryset import QuerySet
def to_dict(obj):
if isinstance(obj, (QuerySet, list)):
return map(to_dict, obj)
elif isinstance(obj, (Document, EmbeddedDocument)):
doc = {}
for field_name, field_type in obj._fields.iteritems():
field_value = getattr(obj, field_name)
doc[field_name] = to_dict(field_value)
return doc
else:
return obj
将此功能称为to_dict(Posts.objects)
或to_dict(Post.objects.first())
,您应该会收到深层词典。
接下来,使用自定义json编码器创建json响应。
import json, bson
def json_response(obj, cls=None):
response = make_response(json.dumps(obj, cls=cls))
response.content_type = 'application/json'
return response
class MongoJsonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, bson.ObjectId):
return str(obj)
if isinstance(obj, bson.DBRef):
return str(obj.id)
return json.JSONEncoder.default(self, obj)
@app.route('/')
def index():
posts_json = to_dict(Post.objects)
return json_response(dict(data=posts_json), cls=MongoJsonEncoder)
答案 1 :(得分:0)
hasattr不适用于属性名称$ oid 例如:
value = {'$oid': '5e8764ed70f190b802bdc008'}
if hasattr(value, '$oid'):
print('this never prints')
我必须以这种方式访问它:
try:
oid = value['$oid']
print('this works')
except:
print('no oid')