我有以下模型和序列化器,目标是序列化器运行时只有一个查询:
模型:
class Assignee(EmbeddedDocument):
id = ObjectIdField(primary_key=True)
assignee_email = EmailField(required=True)
assignee_first_name = StringField(required=True)
assignee_last_name = StringField()
assignee_time = DateTimeField(required=True, default=datetime.datetime.utcnow)
user = ReferenceField('MongoUser', required=True)
user_id = ObjectIdField(required=True)
class MongoUser(Document):
email = EmailField(required=True, unique=True)
password = StringField(required=True)
first_name = StringField(required=True)
last_name = StringField()
assignees= EmbeddedDocumentListField(Assignee)
序列化器:
class MongoUserSerializer(DocumentSerializer):
assignees = AssigneeSerializer(many=True)
class Meta:
model = MongoUser
fields = ('id', 'email', 'first_name', 'last_name', 'assignees')
depth = 2
class AssigneeSerializer(EmbeddedDocumentSerializer):
class Meta:
model = Assignee
fields = ('assignee_first_name', 'assignee_last_name', 'user')
depth = 0
检查 mongo 分析器时,我有 2 个对 MongoUser 文档的查询。如果我从 MongoUserSerializer 中删除 assignees 字段,则只有一个查询。
作为解决方法,我尝试使用 user_id 字段仅存储 ObjectId 并将 AssigneeSerializer 更改为:
class AssigneeSerializer(EmbeddedDocumentSerializer):
class Meta:
model = Assignee
fields = ('assignee_first_name', 'assignee_last_name', 'user_id')
depth = 0
但同样有 2 个查询。我认为序列化程序 EmbeddedDocumentSerializer 获取 ReferenceField 和
的所有字段和查询fields = ('assignee_first_name', 'assignee_last_name', 'user_id')
在查询完成后工作。 如何在序列化时使用 ReferenceField 而不是为每个引用运行单独的查询?
最佳答案
我最终找到了一个解决方法,没有使用 ReferenceField。相反,我使用的是 ObjectIdField:
#user = ReferenceField("MongoUser", required=True) # Removed now
user = ObjectIdField(required=True)
并且改变赋值如下:
- if assignee.user == MongoUser:
+ if assignee.user == MongoUser.id:
这不是最好的方法 - 我们没有使用 ReferenceField 功能,但它比在序列化程序中创建 30 个查询要好。
最好的问候, 克里斯蒂安
关于mongodb - EmbeddedDocumentSerializer 为每个 ReferenceField 运行查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39690805/