开发者社区 问答 正文

介绍文档继承mongnengine时没有提到吗?

我的模型:

class User(mongo_db.Document):
    id = mongo_db.UUIDField(max_length=300, required=True, primary_key=True)
    ...

class Domain(mongo_db.Document):
    id = mongo_db.UUIDField(max_length=300, required=True, primary_key=True)
    creator = mongo_db.ReferenceField(User)
    ...

在创建DomainView对象时,传递某个用户对象的uuid(id)就足够了,这样就可以使工作正常进行(包括写入和检索)。 但是当我向用户模型添加层次结构时:

class GenericUser(mongo_db.Document):
    meta = {'allow_inheritance': True}
    id = mongo_db.UUIDField(max_length=300, required=True, primary_key=True)


class User(GenericUser):
    ...

class Domain(mongo_db.Document):
    id = mongo_db.UUIDField(max_length=300, required=True, primary_key=True)
    creator = mongo_db.ReferenceField(User)
    ...

现在创建一个域对象与创建者设置为某个用户对象的id将引发以下错误:

raise DoesNotExist('Trying to dereference unknown document %s' % value)
mongoengine.errors.DoesNotExist: Trying to dereference unknown document DBRef('generic_user', '4fecbc23-8ecb-4ea6-8fb1-6adf0652e485')

我应该(因为继承)传递一个User对象而不是一个id吗? 问题来源StackOverflow 地址:/questions/59466636/doesnotexist-expetion-when-introducing-document-inhertance-mongnengin

展开
收起
kun坤 2019-12-25 09:44:26 1008 分享 版权
阿里云 AI 助理回答

在MongoEngine中,当你使用ReferenceField时,它期望的是一个文档对象或者该文档的主键值(通常是_id),以便能够正确地解析引用。当你的模型结构引入继承后,问题可能出在MongoEngine如何识别和处理这些继承关系上。

根据你描述的情况,尽管User类继承自GenericUser,但直接传递用户ID作为字符串似乎导致了MongoEngine无法正确解析这个引用,因为它可能在查找引用时没有考虑到继承层次。

解决这个问题的一个方法是确保当你设置或查询creator字段时,你传递的是一个实际的User实例而不是仅仅是一个ID字符串。这可以通过先根据ID加载用户对象,然后将该对象赋给Domaincreator字段来实现:

# 假设user_id是要关联的用户的UUID
user_id = '4fecbc23-8ecb-4ea6-8fb1-6adf0652e485'
user = User.objects.get(id=user_id)  # 确保这里使用的是User对象,不是GenericUser

domain = Domain(creator=user, ...)
domain.save()

这样做的好处是MongoEngine可以明确知道这是哪个具体子类的实例,并且能够正确处理数据库中的引用。

另外,如果你希望继续使用ID字符串并让MongoEngine自动处理这种继承关系,可能需要更深入地配置MongoEngine的映射或考虑是否有必要进行这样的继承设计。在某些情况下,如果继承主要是为了代码组织而非数据模式上的变化,可能需要重新评估这种设计选择,或者探索MongoEngine是否有更直接支持多态引用的方式。

最后,请注意检查MongoEngine的版本和相关文档,因为不同版本之间可能存在行为差异,以及是否有特定于版本的解决方案或配置选项。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答
问答地址: