快速入门
Graphene Django有许多其他的特性, 旨在简化Django开发. 本教程主要聚焦在: 更好的理解, 如何从Django ORM中, 将模型(Model)连接到Graphene的对象类型(object types).
创建Django项目
mkdir cookbook
cd cookbook
# 创建虚拟环境
virtualenv venv #或者 python -m venv venv, 创建虚拟环境目录venv
source env/bin/active #windows使用命令env/Script/active
pip install django graphene_django
# 创建一个项目
django-admin startproject cookbook . #最后的点.别忘记了, 切记
cd cookbook
# 创建一个app
django-admin startapp ingredients
# 迁移数据库模型
cd ..
python manage.py migrate
# 创建超级用户
python manage.py createsuperuser
定义数据库模型
# 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
app加入django设置
# cookbook/settings.py
INSTALLED_APPS = [
...
"graphene_django",
"cookbook.ingredients",
]
数据库迁移
python manage.py makemigrations
python manage.py migrate
填充测试数据
我们来加入一些测试的数据, 在cookbook/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}}]
运行脚本, 填充数据
python manage.py loaddata ingredients
运行结果:
Installed 6 object(s) from 1 fixture(s)
如果需要的话, 可以在django自带的后台加入我们刚刚创建好的数据库模型
# cookbook/ingredients/admin.py
from django.contrib import admin
from cookbook.ingredients.models import Category, Ingredient
admin.site.register(Category)
admin.site.register(Ingredient)
Schema和Object Types
schema可以理解为方案, 在这个方案里, 我们要定义我们需要查(query)什么数据, 改动(mutate)什么数据.
# cookbook/schema.py
import graphene
from graphene_django import DjangoObjectType
from cookbook.ingredients.models import Category, Ingredient
class CategoryType(DjangoObjectType):
class Meta:
model = Category
fields = ("id", "name", "ingredients")
class IngredientType(DjangoObjectType):
class Meta:
model = Ingredient
fields = ("id", "name", "notes", "category")
class Query(graphene.ObjectType):
# 我们定义两条查询的数据
all_ingredients = graphene.List(IngredientType)
category_by_name = graphene.Field(CategoryType, name=graphene.String(required=True))
# 我们要实现我们定义的两条数据, 一般的格式是resolve_+定义的查询数据项
def resolve_all_ingredients(root, info):
return Ingredient.objects.select_related("category").all()
def resolve_category_by_name(root, info, name):
try:
return Category.objects.get(name=name)
except Category.DoesNotExist:
return None
schema = graphene.Schema(query=Query)
Graphene配置
我们需要在项目的settings.py里加入graphene的配置, 并把我们刚刚定义好的schema加入进去.
# cookbook/settings.py
GRAPHENE = {
"SCHEMA": "cookbook.schema.schema"
}
GraphiQL视图
GraphiQL是GraphQL的IDE, 方便我们调试和开发GraphQL.
# cookbook/urls.py
from django.contrib import admin
from django.urls import path
from django.views.decorators.csrf import csrf_exempt
from graphene_django.views import GraphQLView
urlpatterns = [
path("admin/", admin.site.urls),
path("graphql", csrf_exempt(GraphQLView.as_view(graphiql=True))),
]
补充一点:
如果你在Graphene配置中, 没加入我们刚刚定义的Schema, 可以在视图中加入.
# cookbook/urls.py
from django.contrib import admin
from django.urls import path
from django.views.decorators.csrf import csrf_exempt
from graphene_django.views import GraphQLView
from cookbook.schema import schema
urlpatterns = [
path("admin/", admin.site.urls),
path("graphql", csrf_exempt(GraphQLView.as_view(graphiql=True, schema=schema))),
]
运行和调试
python manage.py runserver
我们打开http://localhost:8000/graphql, 输入查询语句
query {
allIngredients {
id
name
}
}
我们会得到如下结果:
{
"data": {
"allIngredients": [
{
"id": "1",
"name": "Eggs"
},
{
"id": "2",
"name": "Milk"
},
{
"id": "3",
"name": "Beef"
},
{
"id": "4",
"name": "Chicken"
}
]
}
}
再使用另一个查询语句
query {
categoryByName(name: "Dairy") {
id
name
ingredients {
id
name
}
}
}
会得到如下结果:
{
"data": {
"categoryByName": {
"id": "1",
"name": "Dairy",
"ingredients": [
{
"id": "1",
"name": "Eggs"
},
{
"id": "2",
"name": "Milk"
}
]
}
}
}