如何使用多对多关系解析石墨烯django节点字段

时间:2018-10-26 17:04:57

标签: django graphql graphene-python

当我尝试解析具有多对多关系的节点字段时,出现“接收到的不兼容实例错误”。我需要帮助来解决此问题。我列出了石墨烯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 个答案:

答案 0 :(得分:0)

由于在没有用法的上下文中,我将提及以下内容。

DjangoObjectType具有一个不错的功能-您可以使用纯Django模型实例代替它,并且:

  1. 随着分辨率的结束,它将转换为graphql类型
  2. 您的self方法中的
  3. 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