All Articles

Server System/Django

Django and GraphQL

Python의 Django와 API로 Restful 방식이 아닌 GraphQL을 사용하여 간단한 프로젝트를 진행해보기로했다.

테스트 날짜: 2020/05/29

 

TODO:

GraphQL에 대한 설명 링크

 

환경 구성과 소스 코드를 살펴보기 위해 아래 사이트들을 참고했다.
Graphene-Django 공식 튜토리얼

Python으로 GraphQL 서버 구현 (Graphene 튜토리얼 따라하기)

Graphene-Django github

moesif-graphene-django-example


Set up the Django project

# 주의: 윈도우 환경
# Create the project directory
mkdir petProject
cd petProject

# Create a virtualenv to isolate our package dependencies locally
virtualenv env
env\Scripts\activate

# Install Django and Graphene with Django support
pip install django
pip install graphene_django

# Set up a new project with a single application
django-admin startproject petbook
cd petbook
django-admin startapp ingredients

 

Migrate project

# migrate django app
python manage.py migrate

 

더보기

Migrate? Makemigrations?

 

Django Command 관련

django-admin

makemigrations? migrate? runserver?


모델 정의 및 설정

# petbook/ingredients/models.py
from django.db import models


class Category(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name


class Ingredient(models.Model):
    name = models.CharField(max_length=100)
    notes = models.TextField()
    category = models.ForeignKey(
        Category, related_name='ingredients', on_delete=models.CASCADE)

    def __str__(self):
        return self.name

 

# petbook/petbook/settings.py
...

INSTALLED_APPS = [
    ... # Required for GraphiQL
    'graphene_django',
    # Install the ingredients app
    #'petbook.ingredients',
    'ingredients',
]

...

 

# Migrate app
python manage.py makemigrations
python manage.py migrate

 


Load test data

# make new json file
# petbook/ingredients/fixtures/ingredients.json
[	
  {
    "model": "ingredients.category", 
    "pk": 1, 
    "fields": {"name": "Dairy"}
  }, 
  {
    "model": "ingredients.category", 
    "pk": 2, 
    "fields": {"name": "Meat"}
  }, 
  {
    "model": "ingredients.ingredient", 
    "pk": 1, 
    "fields": {"name": "Eggs", "notes": "Good old eggs", "category": 1}
  }, 
  {
    "model": "ingredients.ingredient", 
    "pk": 2, 
    "fields": {"name": "Milk", "notes": "Comes from a cow", "category": 1}
  }, 
  {
    "model": "ingredients.ingredient", 
    "pk": 3, 
    "fields": {"name": "Beef", "notes": "Much like milk, this comes from a cow", "category": 2}
  }, 
  {
    "model": "ingredients.ingredient", 
    "pk": 4, 
    "fields": {"name": "Chicken", "notes": "Definitely doesn't come from a cow", "category": 2}
  }
]

 

# Load data
python manage.py loaddata ingredients

Schema와 객체 타입 정의

# petbook/ingredients/admin.py
...

from petbook.ingredients.models import Category, Ingredient

admin.site.register(Category)
admin.site.register(Ingredient)

 

# petbook/ingredients/schema.py
import graphene

from graphene_django.types import DjangoObjectType

#from cookbook.ingredients.models import Category, Ingredient
from cookbook.ingredients.models import Category, Ingredient


class CategoryType(DjangoObjectType):
    class Meta:
        model = Category


class IngredientType(DjangoObjectType):
    class Meta:
        model = Ingredient


class Query(object):
    all_categories = graphene.List(CategoryType)
    all_ingredients = graphene.List(IngredientType)

    def resolve_all_categories(self, info, **kwargs):
        return Category.objects.all()

    def resolve_all_ingredients(self, info, **kwargs):
        # We can easily optimize query count in the resolve method
        return Ingredient.objects.select_related('category').all()

 

# petbook/petbook/schema.py
import graphene

#import petbook.ingredients.schema
import ingredients.schema

#class Query(petbook.ingredients.schema.Query, graphene.ObjectType):
class Query(ingredients.schema.Query, graphene.ObjectType):
    # This class will inherit from multiple Queries
    # as we begin to add more apps to our project
    pass

schema = graphene.Schema(query=Query)

 


Creating GraphQL and GraphiQL views

 

csrf 관련 설명

# petbook/petbook/urls.py
from django.conf.urls import url, include
from django.contrib import admin
from django.views.decorators.csrf import csrf_exempt

from graphene_django.views import GraphQLView

from petbook.schema import schema

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^graphql/', csrf_exempt(GraphQLView.as_view(graphiql=True, schema=schema))),
]

 

 


실행

python manage.py runserver

 

 


결과