当前位置: 代码迷 >> 综合 >> Django+GraphQL 初探
  详细解决方案

Django+GraphQL 初探

热度:60   发布时间:2024-03-07 07:06:56.0

GraphQL 是一种面向 API 的查询语言。通过应用 GraphQL,客户端开发者不必直接与后台 API 接口打交道,而是通过向 GraphQL 声明所需数据结构,从而索取目标数据。GraphQL 的引入能够有效提高客户端的开发效率,使客户端的开发者不再受限于服务器提供的接口,而是能够根据业务需求自由定制需要的数据内容。

GraphQL 现已被较多开发团队所采用,如 Facebook、Twitter、GitHub、Coursera 等。

官方文档:https://graphql.org/
中文文档:https://graphql.cn/learn/
参看视频:https://www.youtube.com/watch?v=ZQL7tL2S0oQ&ab_channel=WebDevSimplified
github地址:https://github.com/graphql
参看文献:
https://docs.graphene-python.org/projects/django/en/latest/
https://blog.csdn.net/ns2250225/article/details/79348914

一.GraphQL 介绍

GraphQL 作为查询语言,开发者通过声明其所需要的数据格式,向 GraphQL Service 发起请求并取得对应的数据。在传统的客户端/服务器通信过程中,客户端向服务器发送网络请求,服务器收到请求后执行相应操作并返回数据。下图展示了未引入 GraphQL 的系统结构:
在这里插入图片描述
引入 GraphQL 后,客户端不再与服务器直接通信,而是通过 GraphQL Service 获取数据。下图展示了引入 GraphQL 的系统结构:
在这里插入图片描述
下图展示了从多个 service 请求特定数据时,引入 GraphQL 的前后对比:
在这里插入图片描述
与传统的客户端/服务器通信模式相比,GraphQL 的引入为整个系统增加了一个中间层,屏蔽了前后端的具体数据结构。其主要优势包括以下几点:

1.定制所需的数据 :客户端可以定制自己想要的数据结构。通过在请求中声明所需的数据结构,从 GraphQL Service 中获取想要的数据。Service 返回的数据结构将与客户端的请求完全一致,从而减少冗余数据的传输。在不使用 GraphQL 的情况下,返回的数据格式不受客户端控制。
2.单个请求获取多个资源 :在 GraphQL 中,客户端不再关心请求的来源,而是直接将需要的资源写入请求字段。在不使用 GraphQL 的情况下,当需要从不同的 Service 取得数据时,客户端开发者需要对不同的 Service 发起请求。
3.结构即文档 :GraphQL 具有友好的调试界面,开发者可直接在该界面中查询 GraphQL 提供的服务。这种数据结构即文档的显示方式,使开发者能够方便快捷地查找所需要的数据类型。
4.订阅功能 :GraphQL 提供订阅功能,使得客户端能够监听数据变化,让 GraphQL Service 能够主动将变动的数据推送至客户端,实时在界面上进行显示。

安装

pip in stall  graphene-django

使用

INSTALLED_APPS = ['graphene_django',
]

models.py

class AuthorGraph(models.Model):name = models.CharField(max_length=255, verbose_name="作者姓名")def __str__(self):return self.name

app下新建schema.py

import graphene
from graphene_django.types import DjangoObjectTypefrom manytable.models import AuthorGraphclass AuthorType(DjangoObjectType):class Meta:model = AuthorGraphclass Query(graphene.ObjectType):users = graphene.List(AuthorType)# List 返回结果会是遍历所有的查询结果single_user = graphene.Field(AuthorType, pk=graphene.Int())# Field 返回结果只存在单个(可添加参数)# 定义函数名的格式: resolve_字段# **kwargs 传递参数# pk: 如果在字段中定义, 则方法参数中必含def resolve_users(self, info, **kwargs):return AuthorGraph.objects.all()def resolve_single_user(self, info, pk):return AuthorGraph.objects.get(id=pk)class TQuery(Query, graphene.ObjectType):passclass CreateUser(graphene.Mutation):# api 的输入参数class Arguments:name = graphene.String(required=True)ok = graphene.Boolean()info = graphene.Field(AuthorType)def mutate(self, info, **kwargs):# print(info.context.user, '==当前用户==')# kwargs 是传递参数中的变量# user = info.context.useruser = AuthorGraph(**kwargs)try:user.save()ok = Trueexcept Exception as e:print(e)ok = Falsereturn CreateUser(ok=ok, info=user)class CMutation(object):create_user = CreateUser.Field()class Mutations(CMutation, graphene.ObjectType):passschema = graphene.Schema(query=TQuery, mutation=Mutations)

urls.py

from graphene_django.views import GraphQLView
from app.schema import schemapath('graphql/', GraphQLView.as_view(graphiql=True, schema=schema)),

请求

请求地址 : http://localhost/graphql
GraphQL 请求参数
mutation createUser {
    createUser (username: "test1") {
    info {
    id,},ok}
}

在这里插入图片描述