I'm very new to Graphene and testing it to see if i could use it for a Django project with complex queries. To test it, i'm trying to create an Ecommerce with the following models
class Sku(models.Model):
name = models.CharField(max_length=100)
class Product(models.Model):
name = models.CharField(max_length=100)
class ProductSku(models.Model):
sku = models.ForeignKey(Sku, related_name='product_sku', on_delete=models.CASCADE)
product = models.ForeignKey(Product, related_name='product_sku', on_delete=models.CASCADE)
price = models.IntegerField()
As you can see here Product and Sku have a many to many relationship using the model ProductSku
Using the documentation from Graphene i created the following Schema
class SkuNode(DjangoObjectType):
class Meta:
model = Sku
class ProductNode(DjangoObjectType):
class Meta:
model = Product
class ProductSkuNode(DjangoObjectType):
class Meta:
model = ProductSku
class Query(graphene.ObjectType):
all_products = graphene.List(ProductNode, name=graphene.String())
product = graphene.Field(ProductNode, id=graphene.Int())
def resolve_all_products(self, info, **args):
name = args.get('name')
if name is not None:
return Product.objects.filter(name__icontains=name)
return Product.objects.all()
def resolve_product(self, info, **args):
id = args.get('id')
if id is not None:
return Product.objects.filter(pk=id).first()
Right now my frontend app could get the price of a given product for a given sku by doing a query that asks for
query{
allProducts{
id,
name,
productSku{
price,
sku{
id,
name
}
}
}
}
But what i want to do is a query that asks for the price inside the SkuNode
query{
allProducts{
id,
name,
sku{
id,
name,
price
}
}
}
Is that posible?
You could add a sku field and resolver to ProductNode
like:
class ProductNode(DjangoObjectType):
sku = graphene.Field(SkuNode)
class Meta:
model = Product
def resolve_sku(self, info):
return self.product_sku.sku # (however you get the Sku object from a Product instance)
Then you'll have a sku
field as part of the product response. But since what you're asking for is to mix fields from both the Sku
and the ProductSku
models, you are probably better off creating a new object type that is not a model type, it's just an ObjectType
with 3 fields (id, name, price) and then dynamically returning an instance of that. So in that case you should do this for ProductNode
class ProductNode(DjangoObjectType):
sku = graphene.Field(SkuObjectType)
class Meta:
model = Product
def resolve_sku(self, info):
sku = self.product_sku.sku
return SkuObjectType(id=sku.id, name=sku.name, price=self.product_sky.price)
And you'd create the SkuObjectType
like
class SkuNode(DjangoObjectType):
id = graphene.ID()
name = graphene.String()
price = graphene.Int()