如何解决具有多对多关系的石墨烯 django 节点字段
Posted
技术标签:
【中文标题】如何解决具有多对多关系的石墨烯 django 节点字段【英文标题】:How to resolve graphene django node field with Many-to-Many relationship 【发布时间】:2019-03-31 11:44:26 【问题描述】:当我尝试使用多对多关系解析节点字段时,我收到“收到不兼容的实例错误”。我需要帮助来解决这个问题。我已经列出了graphene django中的模型,graphql类型以供参考。
我使用的代码版本: 石墨烯 django 版本:2.2.0 python 版本:3.5.2 django 版本:(2, 0, 8, 'final', 0)
models.py
---------
class ModelA:
name
description
Class ModelB:
model_code
description
field3
field4
model_links = models.ManyToManyField(ModelA, through='ModelAModelB')
class ModelAModelB:
model_a = models.ForeignKey('ModelA', null=True, on_delete=models.CASCADE, db_index=False)
model_b = models.ForeignKey('ModelB', null=True, on_delete=models.CASCADE, db_index=False)
class Meta:
#index is defined here
Graphene Django:
Type Definition
---------------
class ModelANode(DjangoObjectType):
class Meta:
model = ModelA
interfaces = (graphene.relay.Node, )
class ModelBNode(DjangoObjectType):
modellinks = graphene.Field(ModelANode)
class Meta:
model = ModelB
interfaces = (graphene.relay.Node, )
def resolve_modellinks(self, info, **args):
#how do i resolve this field
#I tried the below code
modelB = ModelB.objects.get(id=self.id)
modelaIDs = modelB.modelamodelb_set.select_related('model_a').values_list('model_a_id', flat=True)
modelARecs = ModelA.objects.filter(id__in=modelaIDs)
return [graphene.relay.Node.get_node_from_global_id(
'ModelANode',
info,
to_global_id('ModelANode', rec.id)
) for rec in modelARecs]
Graphql Call:
------------
allmodelBs
model_code
description
field3
field4
modellinks
id
我获得了模型 B 字段的数据,但模型链接显示以下错误:
"errors": [
"message": "Received incompatible instance \"[None, None]\"."
,
"message": "Received incompatible instance \"[]\"."
]
我需要帮助来解决多对多关系节点字段。
【问题讨论】:
【参考方案1】:由于没有使用上下文,我将提及以下内容。
DjangoObjectType
有一个不错的功能 - 您可以使用纯 django 模型实例来代替它,并且:
-
分辨率结束会转成graphql类型
self
在您的 resolve_*
方法中将是实际的 django 模型
所以你可以使用它:
modelARecs = [rel.model_a for rel in self.modelamodelb_set.all()]
代替:
modelB = ModelB.objects.get(id=self.id)
modelaIDs = modelB.modelamodelb_set.select_related('model_a').values_list('model_a_id', flat=True)
modelARecs = ModelA.objects.filter(id__in=modelaIDs)
然后返回 modelARecs
,因为它是 django 模型 DjangoObjectType
声明的。
【讨论】:
上下文是这样的。模型 A 和 B 有一个带有数据透视表 AB 的 MTM rel。模型 B 引用了 A 记录列表,因此我试图获取模型 A 的记录列表以匹配 B 记录。我确实按照您的建议替换了代码,但我仍然收到不兼容的实例错误,显示模型名称和值。 我确实找到了一个解决方案,即不在模型 B 节点中向模型 A 添加引用字段,即在上面的示例中删除模型链接。在查询模型 B 节点时,您将能够使用 model_links 自动获取模型 A 的记录,因为它已在模型 A 中引用。以上是关于如何解决具有多对多关系的石墨烯 django 节点字段的主要内容,如果未能解决你的问题,请参考以下文章