开发者

GraphQL在Django中的使用教程

开发者 https://www.devze.com 2022-12-27 09:21 出处:网络 作者: Mr.Lee jack
简介 特点 请求你所要的数据,不多不少获取多个资源,只用一个请求描述所有的可能,类型系统几乎所有语言支持

简介

特点

  • 请求你所要的数据,不多不少
  • 获取多个资源,只用一个请求
  • 描述所有的可能,类型系统
  • 几乎所有语言支持

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="cateandroidgory", 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()


# Ingrpythonedient 查看过滤
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(SerializerMutatio编程客栈n):
    class Meta:
        serializer_class = IngredientSerializer


# 汇总query接口
class ApiQuery(graphene.ObjectType):
    search_category = DjangoFilterConnectionField(CategoryFilter)
    search_ingredient = DjangoFilterConnectionField(IngredientFilter)
开发者_Python入门

# 汇总操作类接口
class ApiMutation(graphene.ObjectType):
    update_category = CategoryMutation.Field()
    update_ingrediphpent = IngredientMutation.Field()

汇总所有接口

import graphene
http://www.devze.com
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实现,如果返回字段中没有改要求,将不会深度查询

到此这篇关于GraphQL在Django中的使用教程的文章就介绍到这了,更多相关GraphQL在Django中的使用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号