Django で GraphQL 実装してみた
ディレクトリ
shemasフォルダを作成
その中に、NodeやQueryなどを記載していく
├── app
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── fixtures
│ │ └── ingredients.json
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── 0002_category_is_active.py
│ │ └── __init__.py
│ ├── models
│ │ ├── __init__.py
│ │ ├── category.py
│ │ └── ingredient.py
│ ├── schema.py
│ ├── schemas
│ │ ├── category.py
│ │ └── ingredient.py
│ ├── tests.py
│ └── views.py
├── config
│ ├── __init__.py
│ ├── asgi.py
│ ├── schema.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py
app/models/__init__.py
from .category import Category
from .ingredient import Ingredient
__all__ = ["Category", "Ingredient"]
app/schemas/category.py
from graphene import relay
from graphene_django import DjangoObjectType
from app.models import Category
class CategoryNode(DjangoObjectType):
class Meta:
model = Category
interfaces = (relay.Node,)
filter_fields = ["name", "ingredients", "is_active"]
app/schemas/ingredient.py
import graphene
from graphene import relay, Mutation
from graphql_relay import from_global_id
from graphene_django import DjangoObjectType
from app.models import Ingredient, Category
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 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"])[1],
)
if input["name"]:
ingredient.name = input["name"]
if input["category_id"]:
category = Category.objects.get(
pk=from_global_id(input["category_id"])[1],
)
ingredient.category_id = category.id
ingredient.save()
return UpdateIngredient(ingredient=ingredient)
app/schema.py
from graphene import relay
from graphene_django.filter import DjangoFilterConnectionField
from app.schemas.category import CategoryNode
from app.schemas.ingredient import IngredientNode, CreateIngredient, UpdateIngredient
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()
とりあえず、ある程度すっきりした
この辺りのアーキテクチャは、改めて考え直すことにする