GraphQL在Django中的使用教程
作者:Mr.Lee jack
这篇文章主要介绍了GraphQL在Django中的使用教程,本文结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
简介
特点
- 请求你所要的数据,不多不少
- 获取多个资源,只用一个请求
- 描述所有的可能,类型系统
- 几乎所有语言支持
文档
GraphQL | A query language for your API
背景
- 传统restful的接口定义类型多,试图简化接口定义
- django中使用restframework定义restful资源接口时,可能会出现深度查询,造成有时候查询过度
- 例如前端用户需要查询接口用于展示在下拉框时,用户仅需要id与value值时,造成无用字段冗余,影响接口返回性能
- 当一张表字段较多时,例如接口1一共有40个字段,A页面需要5个字段做展示,B页面需要另外10个字段展示,这时我们需要根据用户需求定义返回接口提升性能,且数据不会被暴露
实际问题
问题
- 请求数据量40kB可以根据用户缩减,也就是返回数据量可以做到<40KB
- 后端数据实际耗时783ms,但是数据传输一共耗时5s
Django中如何使用呢
安装
安装
pip install graphene-django
django配置
INSTALLED_APPS = [ "django.contrib.staticfiles", "graphene_django" ] GRAPHENE = { "SCHEMA": "test_api.schema.schema" # 下文中需要定义schema.py文件 }
Demo
定义数据库模型
from django.db import models class Category(models.Model): name = models.CharField(max_length=100, help_text="名称") id = models.BigAutoField(primary_key=True) class Ingredient(models.Model): id = models.BigAutoField(primary_key=True) name = models.CharField(max_length=100, help_text="名称") notes = models.TextField(help_text="笔记") category = models.ForeignKey( Category, related_name="category", on_delete=models.CASCADE ) def __str__(self): return self.name
定义serializer
from graphene_django.rest_framework.mutation import SerializerMutation from rest_framework.serializers import ModelSerializer from ..models import Category, Ingredient class CategorySerializer(ModelSerializer): class Meta: model = Category fields = "__all__" class IngredientSerializer(ModelSerializer): class Meta: model = Ingredient fields = "__all__"
定义接口
import graphene from graphene import relay from graphene_django import DjangoObjectType from graphene_django.filter import DjangoFilterConnectionField from graphene_django.rest_framework.mutation import SerializerMutation from ..models import Category, Ingredient from ..serializer import CategorySerializer, IngredientSerializer # 为查询添加查询总数 class CountableConnectionBase(relay.Connection): class Meta: abstract = True total_count = graphene.Int() def resolve_total_count(self, info, **kwargs): return self.iterable.count() # Ingredient 查看过滤 class IngredientFilter(DjangoObjectType): class Meta: model = Ingredient fields = "__all__" filter_fields = { "name": ['exact', "contains", "istartswith"], "category": ["exact"], 'category__name': ['exact'], } interfaces = (relay.Node,) connection_class = CountableConnectionBase extra_field = graphene.String() def resolve_extra_field(self: Ingredient, info): return "hello!" + str(self.id) # CategoryFilter 查询过滤 class CategoryFilter(DjangoObjectType): class Meta: model = Category fields = "__all__" filter_fields = { "name": ['exact', "contains", "istartswith"], } interfaces = (relay.Node,) connection_class = CountableConnectionBase # CategoryMutation 修改或新增 class CategoryMutation(SerializerMutation): class Meta: serializer_class = CategorySerializer # IngredientMutation 修改或新增 class IngredientMutation(SerializerMutation): class Meta: serializer_class = IngredientSerializer # 汇总query接口 class ApiQuery(graphene.ObjectType): search_category = DjangoFilterConnectionField(CategoryFilter) search_ingredient = DjangoFilterConnectionField(IngredientFilter) # 汇总操作类接口 class ApiMutation(graphene.ObjectType): update_category = CategoryMutation.Field() update_ingredient = IngredientMutation.Field()
汇总所有接口
import graphene from .api import ApiQuery, ApiMutation class Query(ApiQuery): # 新增时提供多继承即可 pass class Mutation(ApiMutation): # 新增时提供多继承即可 pass schema = graphene.Schema(query=Query, mutation=Mutation)
启动
python manage.py runserver 0.0.0.0:8080
接口文档
总结
- 查询时,可以使用django_filter , 快速查询
- 用法基本和drf框架基本类似
- 接口面涉及的深度查询,通过connection实现,如果返回字段中没有改要求,将不会深度查询
到此这篇关于GraphQL在Django中的使用教程的文章就介绍到这了,更多相关GraphQL在Django中的使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!