graphene-django学习笔记(一)
一、django基础
1、建立django项目
# Create the project directory mkdir cookbook cd cookbook # Create a virtualenv to isolate our package dependencies locally virtualenv env source env/bin/activate # On Windows use `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 cookbook cd cookbook python manage.py startapp ingredients
2、同步数据库
python manage.py migrate
3、创建models
# cookbook/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
4、注册app
INSTALLED_APPS = [
...
# Install the ingredients app
''ingredients.apps.IngredientsConfig',
]
5、创建并更新数据库表
python manage.py makemigrations python manage.py migrate
6、加载一些数据
在cookbook/ingredients文件夹下创建文件夹fixture,创建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}}]
然后使用
python mangae.py loaddata ingredients
7、创建超级用户
python manage.py createsuperuser
然后输入用户名,密码和邮箱
8、在admin中注册刚刚创建的model,以便于可以登录admin后台进行管理,新增或删除数据。
# cookbook/ingredients/admin.py from django.contrib import admin from .models import Category, Ingredient admin.site.register(Category) admin.site.register(Ingredient)
9、运行服务器
python mangae.py runserver
默认在8000端口,然后打开localhost:8000/admin使用刚才创建的用户名和密码登录。可以看到我们刚才通过json文件加载的数据了。
二、schema 和object types
为了能够像django发送graphql请求,我们需要做下面一些事情:
(1)使用type类型系统创建Schema,
(2)创建一个view接受请求并根据schema返回结果
1、创建app层次的schema
GraphQL将您的对象作为图形结构呈现给世界,而不是您可能习惯的层次结构。为了创建这种表示,Graphene需要知道将出现在图中的每种对象的类型。这意味着我们需要为每一个model创建一个类型系统,继承DjangoObjectType.当我们定义好每个模型对应的type之后,我们可以把这些定义的类型展示在Query下。Query是graphql的一个根类型,graphql有一个还有一些根类型如Query,Mutation,Subscription等
在cookbook/ingredients下定义schema.py
import graphene
from graphene_django import DjangoObjectType
from .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):
return Ingredient.objects.select_related('category').all()
首先使用DjangoObjectType将model中的字段转换为GraphQL对应的type
第二在Query中列示出所有的model,有两个对象分别都是一个列表Type,all_categories和all_Ingerdients。
第三创建resolve_(字段)定义各自的解析函数。
注意这里的Query是一个mixin,我们将要在Django project层面创建一个Query,继承所有app中的Query
2、创建项目顶层的schema
在cookbook/cookbook下创建一个schema
import graphene
import ingredients.schema
class Query(cookbook.ingredients.schema.Query,graphene.ObjectType) :
pass
schema = graphene.Schema(query=Query)
可以把项目顶层的schema视作顶层的路由urls.py
3、注册app,时的graphql_schema可用
INSTALLED_APPS = [
...
# This will also make the `graphql_schema` management command available
'graphene_django',
]
4、为graphene添加schema配置文件
将顶层的schema作为入口文件
GRAPHENE = {
'SCHEMA': 'cookbook.schema.schema'
}
三、创建GraphQL views
与reat api不同,graphQL只需要一个端口来发送所有的请求。
定义url,使用GraphQLView作为接口,graphiql=true默认将显示graphiql工具。
from django.contrib import admin
from django.urls import path
from graphene_django.views import GraphQLView
urlpatterns = [
path('admin/', admin.site.urls),
path('graphql',GraphQLView.as_view(graphiql=True))
]
如果我们没有在Django的settings.py文件中指定schema,也可以在这里设置
from django.conf.urls import url, include
from django.contrib import admin
from graphene_django.views import GraphQLView
from cookbook.schema import schema
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^graphql', GraphQLView.as_view(graphiql=True, schema=schema)),
]
在graphiql中输入查询
{
allCategories{
id
name
ingredients {
id
name
}
}
}
得到结果
{
"data": {
"allCategories": [
{
"id": "1",
"name": "Dairy",
"ingredients": [
{
"id": "1",
"name": "Eggs"
},
{
"id": "2",
"name": "Milk"
}
]
},
{
"id": "2",
"name": "Meat",
"ingredients": [
{
"id": "3",
"name": "Beef"
},
{
"id": "4",
"name": "Chicken"
}
]
}
]
}
}
(1)可以看到schema这里自动转化为了驼峰标志。all_categories自动变成了allCategories
(2)我们这里使用GraphQL可以从category查到ingredients.同时我们也可以进行反向查询,即从ingredients查询到category
四、查询单个对象
在ingredients中增加schema中增加单个对象和相关解析函数。
class Query(object):
category = graphene.Field(CategoryType,
id=graphene.Int(),
name=graphene.String())
all_categories = graphene.List(CategoryType)
ingredient = graphene.Field(IngredientType,
id=graphene.Int(),
name=graphene.String())
all_ingredients = graphene.List(IngredientType)
def resolve_all_categories(self, info, **kwargs):
return Category.objects.all()
def resolve_all_ingredients(self, info, **kwargs):
return Ingredient.objects.all()
def resolve_category(self, info, **kwargs):
id = kwargs.get('id')
name = kwargs.get('name')
if id is not None:
return Category.objects.get(pk=id)
if name is not None:
return Category.objects.get(name=name)
return None
def resolve_ingredient(self, info, **kwargs):
id = kwargs.get('id')
name = kwargs.get('name')
if id is not None:
return Ingredient.objects.get(pk=id)
if name is not None:
return Ingredient.objects.get(name=name)
return None
浙公网安备 33010602011771号