Como obter dados do ReferenceField no mongoengine?
Estou com um problema que a consulta definiu de recuperaçãooid
em json, e gostaria de recuperar o nome de usuário real dessa coleção de usuários que tenho abaixo:
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()
E esse é o resultado que eu recebo:
[{"created_at": {"$date": 1401593024844}, "from_user": {"$oid": "538ad45fb43fdd69076d3e64"}, "subject": "test"}]
Seria bom ter algo assim:
[{"created_at": {"$date": 1401593024844}, "from_user": {"username": "holms"}, "subject": "test"}]
ou de alguma forma semelhante como"from_user" : {"User": {"username":"holms"}}
ATUALIZAR
A resposta acima funciona para o ReferenceField que está no Document, mas e as referências do EmbeddedDocument? Digamos que adicionarei "mensagens" a only ()?
In [97]: inbox = Inbox.objects(messages__to_users__in=[username]).only('from_user', 'subject', 'created_at', 'messages').select_related()
Atualmente, encontrei o caminho mapeando o dicionário, o que é bastante doloroso.
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'}]
ATUALIZAÇÃO 2 Parece ser isso feito o truque
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)
e você entende isso :)
{
"_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"
}
]
}