Graphene Django with SerializerMutation requires foreign key field's id to be passed as a string

130 Views Asked by At

I have two models Category and Item as follows

class Category(models.Model):
    name = models.CharField(max_length=100)
    
    class Meta:
        db_table = 'categories'

    def __str__(self):
        return self.name

class Item(models.Model):
    name = models.CharField(max_length=100)
    category = models.ForeignKey('Category', on_delete=models.DO_NOTHING, null=True, blank=True, related_name='related_items')
    
    class Meta:
        db_table = 'items'

    def __str__(self):
        return self.name

and I have simple Mutation classes which I have created as follows which subclasses SerializerMutation

from graphene_django.rest_framework.mutation import SerializerMutation

class CategoryMutation(SerializerMutation):
    class Meta:
        serializer_class = CategorySerializer
        model_operation = ['create', 'update']
        lookup_field = 'id'

class ItemMutation(SerializerMutation):
    class Meta:
        serializer_class = ItemSerializer
        model_operation = ['create', 'update']
        lookup_field = 'id'

class Mutation(graphene.ObjectType):
    cud_category = CategoryMutation.Field()
    cud_item = ItemMutation.Field()

My serializers are also simple ModelSerializers which are as follows:

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = ['id', 'name']

class ItemSerializer(serializers.ModelSerializer):
    class Meta:
        model = Item
        fields = ['id', 'name', 'category']

Now I am able to perform a create mutation for Category as below

THE QUERY

mutation{
  cud_category(input:{name: "category_1"}) {
    id
    name
  }
}

and get a return as follows

THE OUTPUT

{
  "data": {
    "cud_category": {
      "id": 30,
      "name": "category_1"
    }
  }
}

Now when I try creating an Item as follows ---> Here is where the issue starts

THE QUERY

mutation{
  cud_item(input:{name: "item_1" category: 30}) {
    id
    name
  }
}

It errors out as follows

THE OUTPUT

{
  "errors": [
    {
      "message": "String cannot represent a non string value: 1",
      "locations": [
        {
          "line": 2,
          "column": 43
        }
      ]
    }
  ]
}

it works when I make category: 30 as category: "30"

THE QUERY

mutation{
  cud_item(input:{name: "item_1" category: "30"}) {
    id
    name
  }
}

It works and I can see the creation in the database

THE OUTPUT

{
  "data": {
    "cud_item": {
      "id": 27,
      "name": "item_1"
    }
  }
}

What am I doing wrong here? and Why are foreign keys string in this case? How can I make it more dynamic to have objects of my foreign key entity instead of string ids?

I want something like this

mutation{
  cud_item(input:{name: "item_1" category: {id: 30 name: "category_1"}) {
    id
    name
  }
}

PS: I did spend hours searching through SO and other websites to find a solution, and I do know I can go the InputObjectType way, but I have many drf serializers already written and wanted to know if I can achieve it via SerializerMutation

0

There are 0 best solutions below