2024年在线市场平台的11大最佳支付解决方案
为 Django 配备 GraphQL API
提出问题
首先,我们先提出一个小小的需求,针对这个小小的需求,设计代码。
假如要开发一个菜谱应用,要支持原材料的录入和分类,前端需要灵活的展示某个原材料属于哪个分类,某个分类下有哪些原材料,并且可以传入参数查询。
请编码实现原材料和分类的灵活查询。
解决问题
接下来,我们创建 Django 应用解决问题。
1、先安装 django,graphene-django。graphene-django 就是为 Django 提供 GraphQL API 的三方库。
pip install django
pip install graphene-django
2、生成 Django 初始代码,编写 models.py,编写 GraphQL 的模式。
django-admin startproject cookbook
cd cookbook
python manage.py startapp ingredients
修改 models.py 文件,添加两个类,一个是对应分类,别一个对应原料,修改后内容如下所示:
from django.db import models
# Create your models here.
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
外键代表两者之间的关系:一个分类下面可以有多个原料,但一个原料只能属于某一个分类。
然后,我们在 settings.py 同一级的目录,新增一个 schema.py 文件,内容如下:
import graphene
from graphene_django import DjangoObjectType
from 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)
all_categorys = graphene.List(CategoryType)
category_by_name = graphene.Field(CategoryType, name=graphene.String(required=True))
def resolve_all_categorys(root, info):
return Category.objects.all()
def resolve_all_ingredients(root, info):
# We can easily optimize query count in the resolve method
return Ingredient.objects.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)
schema 是 GraphQL 的核心代码,Query 类和 models 类很像,对比着写代码就可以了,后面熟悉之后再理解它的原理。
接着,我们在 settings.py 的 INSTALLED_APPS 添加两条记录:
"ingredients.apps.IngredientsConfig",
"graphene_django",
配置 cookbook.urls 使用刚才创建的 schema, 内容如下:
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))),
]
3、建表,插入测试数据。
(py38env) ➜ cookbook python manage.py makemigrations
Migrations for 'ingredients':
ingredients/migrations/0001_initial.py
- Create model Category
- Create model Ingredient
(py38env) ➜ cookbook python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, ingredients, sessions
Running migrations:
Applying ingredients.0001_initial... OK
(py38env) ➜ cookbook ls
cookbook db.sqlite3 ingredients manage.py
至此,db.sqlite3 中已经有了两张表,接下来插入测试数据,数据来源:ingredients.json
下载后保存到项目的根目录,也就是第一个 cookbook 目录下,然后执行下面的命令导入测试数据:
(py38env) ➜ cookbook python manage.py loaddata ingredients.json
Installed 6 object(s) from 1 fixture(s)
4、启动服务,并测试。
python manage.py runserver
浏览器打开 http://localhost:8000/graphql/
就可以看到如下页面:
这就是 GraphQL 的接口调试界面,左边输入查询条件,右边返回数据。
比如查一下所有的原料表:
query {
allIngredients {
id
name
note
}
}
接下来反着查一下,比如查询所有的分类:
query {
allCategorys {
id
name
}
}
查询所有的分类及对应的原料信息:
query {
allCategorys {
id
name
ingredients{
id
name
notes
}
}
}
查询某一分类,比如乳制品分类下面的原料信息:
query {
categoryByName(name: "Dairy") {
id
name
ingredients {
id
name
}
}
}
总结
GraphQL 非常强大,并且可以快速集成 Django 模型,从而可以非常方便的将你的应用 api 转换为 GraphQL 风格。
文章转自微信公众号@Python七号