网络编程
位置:首页>> 网络编程>> Python编程>> GraphQL在Django中的使用教程

GraphQL在Django中的使用教程

作者:Mr.Lee  发布时间:2023-02-20 18:11:31 

标签:GraphQL,Django,使用

简介

特点

  • 请求你所要的数据,不多不少

  • 获取多个资源,只用一个请求

  • 描述所有的可能,类型系统

  • 几乎所有语言支持

GraphQL在Django中的使用教程

文档

Graphene-Python

GraphQL | A query language for your API

GraphQL在Django中的使用教程

背景

  • 传统restful的接口定义类型多,试图简化接口定义

  • django中使用restframework定义restful资源接口时,可能会出现深度查询,造成有时候查询过度

  • 例如前端用户需要查询接口用于展示在下拉框时,用户仅需要id与value值时,造成无用字段冗余,影响接口返回性能

  • 当一张表字段较多时,例如接口1一共有40个字段,A页面需要5个字段做展示,B页面需要另外10个字段展示,这时我们需要根据用户需求定义返回接口提升性能,且数据不会被暴露

实际问题

GraphQL在Django中的使用教程

GraphQL在Django中的使用教程

问题

  • 请求数据量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

接口文档

GraphQL在Django中的使用教程

GraphQL在Django中的使用教程

总结

  • 查询时,可以使用django_filter , 快速查询

  • 用法基本和drf框架基本类似

  • 接口面涉及的深度查询,通过connection实现,如果返回字段中没有改要求,将不会深度查询

来源:https://blog.csdn.net/xzpdxz/article/details/128436581

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com