LoginSignup
0
0

Django で GraphQL 実装してみた Mutation編

Last updated at Posted at 2024-06-25

Django で GraphQL 実装してみた

実装

createメソッド追加

app/schema.py

class IngredientNode(DjangoObjectType):
    class Meta:
        model = Ingredient
        interfaces = (relay.Node,)
        filter_fields = {
            "name": ["exact", "icontains", "istartswith"],
            "notes": ["exact", "icontains"],
            "category": ["exact"],
            "category__name": ["exact"],
            "category__is_active": ["exact"],
        }

        
+ class CreateIngredient(Mutation):
+    class Arguments:
+        name = graphene.String(required=True)
+        category_id = graphene.ID(required=True)
+
+   ingredient = graphene.Field(IngredientNode)
+
+    def mutate(self, info, **input):
+        ingredient = Ingredient(
+            name=input["name"],
+            category_id=input["category_id"],
+        )
+        ingredient.save()
+        return CreateIngredient(ingredient=ingredient)    


class Query:
    category = relay.Node.Field(CategoryNode)
    categories = DjangoFilterConnectionField(CategoryNode)

    ingredient = relay.Node.Field(IngredientNode)
    ingredients = DjangoFilterConnectionField(IngredientNode)

    
+ class Mutation:
+     create_ingredient = CreateIngredient.Field()

create mutation実行

createIngredientの中に、queryで取得したい値を指定することができる。

mutation{
  createIngredient(name:"new item name", categoryId:"1"){
    ingredient{
      id
      name
      category {
        id
        name
      }
    }
  }
}

relayのIDを解決する

idは、base64エンコードされるため、DBに保存する際は本来の値を保存したい。
from_global_idメソッドを使用する。
戻り値は(type, id)
typeは、DjangoObjectTypeのクラス名、idはDBの値
※今回の場合、typeはIngredientNodeとなる

app/schema.py

+ from graphql_relay import from_global_id

...

class CreateIngredient(Mutation):
    class Arguments:
        name = graphene.String(required=True)
        category_id = graphene.ID(required=True)

    ingredient = graphene.Field(IngredientNode)

    def mutate(self, info, **input):
+       category_node = from_global_id(input["category_id"])
        ingredient = Ingredient(
            name=input["name"],
-           category_id=input["category_id"],
+           category_id=category_node.id,
        )
        ingredient.save()
        return CreateIngredient(ingredient=ingredient)

updateメソッド追加

app/schema.py

class CreateIngredient(Mutation):
    class Arguments:
        name = graphene.String(required=True)
        category_id = graphene.ID(required=True)

    ingredient = graphene.Field(IngredientNode)

    def mutate(self, info, **input):
        ingredient = Ingredient(
            name=input["name"],
            category_id=input["category_id"],
        )
        ingredient.save()
        return CreateIngredient(ingredient=ingredient)


+ class UpdateIngredient(Mutation):
+     class Arguments:
+         id = graphene.ID(required=True)
+         name = graphene.String()
+         category_id = graphene.String()
+
+     ingredient = graphene.Field(IngredientNode)
+
+     def mutate(self, info, **input):
+         ingredient = Ingredient.objects.get(
+             pk=from_global_id(input["id"]).id,
+         )
+         if input["name"]:
+             ingredient.name = input["name"]
+         if input["category_id"]:
+             node = from_global_id(input["category_id"])
+             ingredient.category_id = node.id
+             
+         ingredient.save()
+         return UpdateIngredient(ingredient=ingredient)



class Query:
    category = relay.Node.Field(CategoryNode)
    categories = DjangoFilterConnectionField(CategoryNode)

    ingredient = relay.Node.Field(IngredientNode)
    ingredients = DjangoFilterConnectionField(IngredientNode)

    
class Mutation:
    create_ingredient = CreateIngredient.Field()
+   update_ingredient = UpdateIngredient.Field()

update mutation実行

mutation {
  updateIngredient(id:"SW5ncmVkaWVudE5vZGU6MQ==", name:"update", categoryId:"Q2F0ZWdvcnlOb2RlOjE="){
    ingredient {
      id
      name
      category {
        id
        name
      }
    }
  }
}

次は、リファクタ編

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0