django - graphene-django:查询所有模型字段而不是请求的字段
问题描述
我有两个模型:
class Type(models.Model):
name = models.CharField(max_length=255)
def __str__(self):
return f'{self.name}'
class Pet(models.Model):
name = models.CharField(max_length=255)
color = models.CharField(max_length=255)
type = models.ForeignKey(Type, related_name="pets", on_delete=models.CASCADE,
null=True, blank=True)
def __str__(self):
return f'{self.type.name} {self.name}'
架构:
class Type(DjangoObjectType):
class Meta:
model = TypeModel
@classmethod
def get_node(cls, info, id):
return TypeModel.objects.get(id=id)
class TypeConnector(graphene.Connection):
count = graphene.Int()
class Meta:
node = Type
def resolve_count(root, info):
return len(root.edges)
class Pet(DjangoObjectType):
class Meta:
model = PetModel
interfaces = (relay.Node,)
@classmethod
def get_node(cls, info, id):
return PetModel.objects.get(id=id)
class PetConnector(graphene.Connection):
count = graphene.Int()
class Meta:
node = Pet
def resolve_count(root, info):
return len(root.edges)
class Schema(ObjectType):
pets = graphene.ConnectionField(PetConnector)
types = graphene.ConnectionField(TypeConnector)
def resolve_pets(self, info, **kwargs):
# TODO: Query for requested fields only
return PetModel.objects.all()
def resolve_types(self, info, **kwargs):
# TODO: Query for requested fields only
return TypeModel.objects.all()
GraphQL 的目标之一是性能。要做到这一点,GraphQL 必须通过 GraphQL 请求仅向数据库请求请求的字段(例如:GraphiQL)
如果我请求以下查询:
{
pets {
edges {
node {
color
type {
name
}
}
}
}
}
graphene-django 库生成以下 SQL:
2020-01-03 03:16:18.184 UTC [136] LOG: statement: SELECT "pets_pet"."id", "pets_pet"."name", "pets_pet"."color", "pets_pet"."type_id" FROM "pets_pet"
2020-01-03 03:16:18.189 UTC [136] LOG: statement: SELECT "pets_type"."id", "pets_type"."name" FROM "pets_type" WHERE "pets_type"."id" = 1 LIMIT 21
它得到了模型的所有领域!与 API Rest 问题相同,并且不符合 GraphQL 指南。
如果我color
从pets
模型中请求字段,我希望查询是:
SELECT "pets_pet"."color" FROM "pets_pet"
而且......外键如何用这种方法解决?
解决方案
您可以尝试使用graphene-django-optimizer。
它的作用是优化您的查询,以便您在一个查询中获取所有相关对象。
在您的情况下,这可能是您的解析器:
import graphene_django_optimizer as gql_optimizer
...
class Schema(ObjectType):
pets = graphene.ConnectionField(PetConnector)
types = graphene.ConnectionField(TypeConnector)
def resolve_pets(self, info, **kwargs):
return gql_optimizer.query(PetModel.objects.all(), info)
它将自动生成以下查询集:
Pets.objects
.select_related('type')
.only('color', 'type__name')
推荐阅读
- java - 为什么我的 onBindViewHolder () 根本没有运行,即使我的所有其他回收器视图方法都运行了?
- javascript - handle multiselect case on selecting and deselecting button/component
- swift - SwiftUI 中带有自定义绑定的可选扩展
- postgresql - 创建一个带有括号的列名的表
- jvm - Java字节码,调用方法不能正常工作
- powerbi - Power BI 自定义视图(与 tableu 类似)
- python - 我应该使用 OAuth2 身份验证吗?
- mysql - 对于这些约束,合适的表/数据库设计是什么?
- sql-server - 用其他表触发函数,但不是这个表。消息 102
- snowflake-cloud-data-platform - 将雪花运行时错误发送到 Amazon Notification Service(SNS)