我有一个相当重的User
文档类,我想将它分成两部分:文档中的用户个人资料(姓名和头像)和UserProfile
文档中的其余部分User
,如下所示(使用 MongoEngine):
from mongoengine import *
class User(Document):
login = StringField()
password = StringField()
posts = ListField(ReferenceField("Post", dbref = False))
#... a bunch of other fields
class UserProfile(Document):
name = StringField()
avatar = URLField()
我希望 UserProfile 和 User 具有相同的 ObjectId,这样我只需要一个 ObjectId 来引用 User 和 UserProfile。毕竟,这实际上是一对一的关系,而且由于用户可以撰写许多帖子,我不想将她的个人资料嵌入帖子本身。创建用户文档时,我会立即创建相应的配置文件,如下所示:
john = User.objects.create(login = "john", password = "super!password")
john_profile = UserProfile.objects.create(id = john.id, name = "John Smith",
avatar = "http://www.example.com/img/photo.jpg")
到目前为止,一切都很好。现在我有一个Post
文档,其中包含一个author
引用该User
文档的字段:
class Post(Document):
author = ReferenceField("User", dbref = False)
text = StringField()
我想添加一个author_profile
引用,基于相同的 ObjectId。我试过这个:
class Post(Document):
author = ReferenceField("User", dbref = False)
author_profile = ReferenceField("User", db_field = "author", dbref = False)
text = StringField()
但我得到以下异常:
mongoengine.base.InvalidDocumentError: Multiple db_fields defined for: author
所以看来我必须“手动”这样做。可能是这样的:
class Post(Document):
author = ReferenceField("User", dbref = False)
text = StringField()
@property
def author_profile(self):
if hasattr(self, "_author_profile"):
return self._author_profile
self._author_profile = UserProfile.objects.get(id = self._data["author"].id)
return self._author_profile
我想这还不错,但是没有更好的解决方案吗?
谢谢。
注意:我阅读了关于一对一关系的mongodb 文档,以及mongoengine ReferenceField 文档,但它对这个特定问题没有帮助。