Graphene-Django 임시

x·2022년 9월 27일
0

pycharm에서 django 프로젝트 생성

terminal에서 pip install graphene

아래 코드의 execute 메서드 내 query문을 보면 python 코딩 컨벤션인 snake case가 아닌 camel case다. is_staff로 사용하고 싶으면 두 가지 방법이 있다
스키마 설정 시 camel case 해제
schema = graphene.Schema(query=Query, auto_camelcase=False)
또는
필드 정의 시 name 지정
is_staff = graphene.Boolean(name='is_staff')

schema.py

import graphene
import json


class Query(graphene.ObjectType):
    # 필드 지정
    is_staff = graphene.Boolean()

    # is_staff 필드를 resolve하는 메서드
    # info의 역할은? query의 context를 담음
    def resolve_is_staff(self, info):
        return True


schema = graphene.Schema(query=Query)

result = schema.execute(
    """
    {
        is_staff
    }
    """
)

# data는 result의 attribute다
items = dict(result.data.items())
print(json.dumps(items, indent=4))

결과

{
    "is_staff": true
}

user class 만들기

User type에 id, username, last_login 필드를 정의했다.
Query 클래스에서 graphene List 타입에 User 클래스를 넘겨서 여러 개의 User를 반환한다고 지정한다. first는 resolve 메서드에서 사용하는 변수다.

execute 메서드에서 users 필드를 요청할 때 first라는 인수를 넘긴다.

schema.py

import graphene
import json
from datetime import datetime


class User(graphene.ObjectType):
    id = graphene.ID()
    username = graphene.String()
    last_login = graphene.DateTime()


class Query(graphene.ObjectType):
    # 필드 지정
    users = graphene.List(User, first=graphene.Int())

    def resolve_users(self, info, first):
        return [
            User(id=1, username="hi1", last_login=datetime.now()),
            User(id=2, username="hi2", last_login=datetime.now()),
            User(id=3, username="hi3", last_login=datetime.now()),
        ][:first]

schema = graphene.Schema(query=Query)

result = schema.execute(
    """
    {
        users (first:3) {
            id
            username
            lastLogin
        }
    }
    """
)

print(json.dumps(result.data, indent=4))

mutations
schema를 정의할 때 mutation=Mutation을 추가해준다
schema = graphene.Schema(query=Query, mutation=Mutations)

execute 메서드를 보면 mutation으로 시작한다. query와 다르게 create, update, delete를 한다. DB에 변경을 가하는 요청이라고 보면 된다.
mutation 옆에 createUser는 뮤테이션 이름이라 해당 요청을 식별할 수 있는 이름을 지어주면 된다. 그 안에 createUser는 CreateUser 타입을 이용해 username을 넘기고 user를 생성하고 username을 반환 받게 된다. 뮤테이션 요청을 graphql 서버에서 실행하면 createUser type을 찾고 mutate 메서드를 실행한다. User 인스턴스를 만들고 CreateUser 인스턴스에 user 필드를 채워 반환한다

import graphene
import json
from datetime import datetime


class User(graphene.ObjectType):
    id = graphene.ID()
    username = graphene.String()
    last_login = graphene.DateTime(required=False)


class Query(graphene.ObjectType):
    # 필드 지정
    users = graphene.List(User, first=graphene.Int())

    def resolve_users(self, info, first):
        return [
            User(id=1, username="hi1", last_login=datetime.now()),
            User(id=2, username="hi2", last_login=datetime.now()),
            User(id=3, username="hi3", last_login=datetime.now()),
        ][:first]


class CreateUser(graphene.Mutation):

    class Arguments:
        username = graphene.String()

    user = graphene.Field(User)

    def mutate(self, info, username):
        user = User(username=username)

        return CreateUser(user=user)


class Mutations(graphene.ObjectType):
    create_user = CreateUser.Field()


schema = graphene.Schema(query=Query, mutation=Mutations)

result = schema.execute(
    """
    mutation createUser {
        createUser (username: "hi") {
            user {
                username
            }
        }
    }
    """
)

print(json.dumps(result.data, indent=4))

변수, context 사용
mutation 요청할 때 variable_values dict에 값을 넣는다. mutation에서 $username으로 변수를 받고 : String으로 타입을 명시한다. createUser 필드에서는 username 변수를 mutation 메서드에 넘긴다.
context에는 로그인한 사용자, db 액세스 같은 문맥 정보를 넣는데 여기서는 vip인지 판단하기 위한 플래그를 전달했고 mutation 메서드 안에서 vip 여부에 따라 대문자로 만들어준다.

import graphene
import json
from datetime import datetime


class User(graphene.ObjectType):
    id = graphene.ID()
    username = graphene.String()
    last_login = graphene.DateTime(required=False)


class Query(graphene.ObjectType):
    # 필드 지정
    users = graphene.List(User, first=graphene.Int())

    def resolve_users(self, info, first):
        return [
            User(id=1, username="hi1", last_login=datetime.now()),
            User(id=2, username="hi2", last_login=datetime.now()),
            User(id=3, username="hi3", last_login=datetime.now()),
        ][:first]


class CreateUser(graphene.Mutation):

    class Arguments:
        username = graphene.String()

    user0 = graphene.Field(User)

    def mutate(self, info, username):
        print('info', info.context['is_vip'])
        username = username.upper() if info.context['is_vip'] else username
        user2 = User(username=username)

        return CreateUser(user0=user2) 


class Mutations(graphene.ObjectType):
    create_user = CreateUser.Field()


schema = graphene.Schema(query=Query, mutation=Mutations)

# query
result = schema.execute(
    """
    query getUser {
        users (first: 2) {
            username
        }
    }
    """
)

print("query : ")
print(json.dumps(result.data, indent=4))

# mutation
result = schema.execute(
    """
    mutation createUser ($username: String) {
        createUser (username: $username) {
            user0 {
                username
                lastLogin
            }
        }
    }
    """,
    variable_values={
        'username': 'Bob'
    },
    context={
        'is_vip': True
    }
)


print("mutation : ")
print(json.dumps(result.data, indent=4))

graphene-django
pip install graphene-django==3.0.0b7로 설치
python manage.py startapp snippets로 새 앱 생성
settings.py의 INSTALLED_APPS 리스트에 아래 추가

    'snippets',
    'graphene_django'

snippets 앱에 schema.py 파일 생성

models.py에 모델을 생성하고
schema.py에 Snippet 모델을 활용해 객체 타입을 생성하고 Query에는 필드와 resolver를 작성해준다.

https://docs.graphene-python.org/en/latest/quickstart/

0개의 댓글