如何在Django(Graphene)中按App分组GraphQL查询与变更?
问题
正在将REST API端点迁移至基于Graphene的GraphQL,已实现基础功能,但希望像REST中app_1/endpoint、app_2/endpoint那样,将Django各App的Graphene查询和变更按App分组。
当前实现方式:每个App内创建graphql文件夹存放查询与变更文件,主Schema中合并所有App元素到统一的query和mutation对象:
# app1/graphql/queries.py class Endpoint1(DjangoObjectType): class Meta: model = Element1 fields = ("id", "name", "date") # app2/graphql/queries.py class Endpoint2(DjangoObjectType): class Meta: model = Element2 fields = ("id", "name", "date") # django_project/graphql/queries.py class Queries(Endpoint1, Endpoint2): pass
当前查询结构是所有端点平铺在query下:
query { endpoint1 { id name } endpoint2 { id name } }
希望实现按App分组的查询结构,示例如下:
query { app1 { endpoint1 { id name } } } query { app2 { endpoint2 { id name } } }
解决方案
完全可行,核心思路是为每个App创建独立的查询容器类型,再将这些容器作为根级字段整合到主Query中,具体步骤如下:
1. 为每个App定义查询容器类型
在各App的graphql/queries.py中,除了原有的DjangoObjectType,新增一个封装该App所有查询的ObjectType:
# app1/graphql/queries.py import graphene from graphene_django import DjangoObjectType from .models import Element1 class Endpoint1(DjangoObjectType): class Meta: model = Element1 fields = ("id", "name", "date") # 封装App1所有查询的容器类型 class App1Queries(graphene.ObjectType): endpoint1 = graphene.List(Endpoint1) # 根据需求选择List/Field/SingleField等类型 def resolve_endpoint1(self, info, **kwargs): return Element1.objects.all()
同理处理app2:
# app2/graphql/queries.py import graphene from graphene_django import DjangoObjectType from .models import Element2 class Endpoint2(DjangoObjectType): class Meta: model = Element2 fields = ("id", "name", "date") # 封装App2所有查询的容器类型 class App2Queries(graphene.ObjectType): endpoint2 = graphene.List(Endpoint2) def resolve_endpoint2(self, info, **kwargs): return Element2.objects.all()
2. 在主Schema中整合各App的容器字段
修改主查询文件,将每个App的查询容器作为根级字段添加到主Query:
# django_project/graphql/queries.py import graphene from app1.graphql.queries import App1Queries from app2.graphql.queries import App2Queries class Query(graphene.ObjectType): # 为每个App添加根级字段,关联对应的查询容器 app1 = graphene.Field(App1Queries) app2 = graphene.Field(App2Queries) # 解析App容器字段(直接返回实例即可,内部查询的resolve由容器自身处理) def resolve_app1(self, info): return App1Queries() def resolve_app2(self, info): return App2Queries()
3. 更新主Schema定义
确保主Schema使用新的Query类:
# django_project/graphql/schema.py import graphene from .queries import Query schema = graphene.Schema(query=Query)
完成以上配置后,就可以实现你想要的按App分组的查询结构,测试查询与你给出的示例完全一致。
对于变更(Mutation),可复用相同逻辑:为每个App创建App1Mutations、App2Mutations这类ObjectType,再将它们作为字段整合到主Mutation中,即可实现变更的按App分组。
内容的提问来源于stack exchange,提问作者Eddysanoli
相关产品推荐
相关产品推荐

