阅读 178

02#快速入门-Graphene-Django系统学

快速入门

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"
        }
      ]
    }
  }
}
复制代码
文章分类
后端
文章标签