我遇到一个问题,查询集在json中检索oid
,我想检索我在下面的用户集合的实际用户名:
class User(db.Document):
username = db.StringField(required=True)
password_hash = db.StringField()
is_admin = db.IntField(default=0)
class Message(db.EmbeddedDocument):
to_users = db.ListField(db.ReferenceField(User))
created_at = db.DateTimeField(default=datetime.now)
is_read = db.BooleanField(default=False)
body = db.StringField(required=True)
class Inbox(db.Document):
from_user = db.ReferenceField(User, required=True)
subject = db.StringField(max_length=255, required=True)
created_at = db.DateTimeField(default=datetime.now)
messages = db.ListField(db.EmbeddedDocumentField(Message))
username = User().get_username()
username = User.objects(username=username).first()
inbox = Inbox.objects.filter(messages__to_users__in=[username]).only('from_user', 'subject', 'created_at').to_json()
这就是我得到的结果:
[{"created_at": {"$date": 1401593024844}, "from_user": {"$oid": "538ad45fb43fdd69076d3e64"}, "subject": "test"}]
拥有这样的东西会很高兴:
[{"created_at": {"$date": 1401593024844}, "from_user": {"username": "holms"}, "subject": "test"}]
或以某种方式类似"from_user" : {"User": {"username":"holms"}}
更新
上面的答案适用于Document中的ReferenceField,但是EmbeddedDocument引用呢?假设我只将“消息”添加到()?
In [97]: inbox = Inbox.objects(messages__to_users__in=[username]).only('from_user', 'subject', 'created_at', 'messages').select_related()
目前我已经通过映射字典找到了相当痛苦的方法。
In [125]: for entry in inbox:
item = dict(subject=entry.subject, messages=map(lambda msg: dict(body=msg.body, is_read=msg.is_read, to_users=map(lambda usr: usr.username, msg.to_users)), entry.messages), from_user=entry.from_user.username)
result.append(item)
.....:
In [126]: result
Out[126]:
[
{'from_user': u'holms',
'messages': [{'body': u'test body',
'is_read': False,
'to_users': [u'holms']}],
'subject': u'test'}]
更新2 似乎是这样做的伎俩
57 def to_json(self):
58 data = self.to_mongo() # get pymongo representation
59 data["from_user"] = {"User": {"username": self.from_user.username} }
60
61 for key, reply in enumerate(data["messages"]):
62 for user in self.messages[key].to_users:
63 print user.username
64 reply["to_users"] = {"User": {"username": user.username} }
65
66 return json_util.dumps(data)
你得到了这个:)
{
"_id":{
"$oid":"538ad500b43fdd690e2eefb5"
},
"from_user":{
"User":{
"username":"holms"
}
},
"subject":"test",
"created_at":{
"$date":1401593024844
},
"messages":[
{
"to_users":{
"User":{
"username":"holms"
}
},
"created_at":{
"$date":1401593024845
},
"is_read":false,
"body":"test body"
}
]
}
答案 0 :(得分:6)
目前不支持直接,因为MongoEngine仅支持mongodb的扩展json语法。
所有mongoengine都在使用pymongo的json_utils
来转储数据。没有理由不能明确地使用它,例如:
from bson import json_util
class Inbox(db.Document):
from_user = db.ReferenceField(User, required=True)
subject = db.StringField(max_length=255, required=True)
created_at = db.DateTimeField(default=datetime.now)
messages = db.ListField(db.EmbeddedDocumentField(Message))
def to_json(self):
data = self.to_mongo() // get the pymongo representation of the document
data["from_user"] = {"User": {"username": self.from_user.username}}
return json_util.dumps(data)
User.drop_collection()
...
Inbox.drop_collection()
ross = User(username="Ross").save()
Inbox(from_user=ross, subject="Mongoengine should make json easier").save()
doc = Inbox.objects.only('from_user', 'subject', 'created_at').get()
print doc.to_json()
{"_id": {"$oid": "538c3d71c3d384172fe35393"},
"from_user": {"User": {"username": "Ross"}},
"subject": "Mongoengine should make json easier",
"created_at": {"$date": 1401703297198}, "messages": []}
自定义查询集的示例:
from bson import json_util
class CustomQuerySet(QuerySet):
def to_json(self):
return "[%s]" % (",".join([doc.to_json() for doc in self]))
class Inbox(Document):
from_user = ReferenceField(User, required=True)
subject = StringField(max_length=255, required=True)
created_at = DateTimeField(default=datetime.now)
messages = ListField(EmbeddedDocumentField(Message))
meta = {'queryset_class': CustomQuerySet}
def to_json(self):
data = self.to_mongo()
data["from_user"] = {"User": {"username": self.from_user.username}}
return json_util.dumps(data)
...
ipdb> Inbox.objects.only('from_user', 'subject', 'created_at').to_json()
'[{"_id": {"$oid": "538d84cbc3d3843eeeb5dbbe"},
"from_user": {"User": {"username": "Ross"}},
"subject": "Mongoengine should make json easier",
"created_at": {"$date": 1401787099246}, "messages": []}]'