GraphQL在Django中的使用教程

 更新时间:2022年12月26日 10:19:14   作者:Mr.Lee jack  
这篇文章主要介绍了GraphQL在Django中的使用教程,本文结合示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

简介

特点

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

文档

Graphene-Python

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中的使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • 使用python远程操作linux过程解析

    使用python远程操作linux过程解析

    这篇文章主要介绍了使用python远程操作linux过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • 在Python程序中实现分布式进程的教程

    在Python程序中实现分布式进程的教程

    这篇文章主要介绍了在Python程序中实现分布式进程的教程,在多进程编程中十分有用,示例代码基于Python2.x版本,需要的朋友可以参考下
    2015-04-04
  • 玩转Python图像处理之二值图像腐蚀详解

    玩转Python图像处理之二值图像腐蚀详解

    这篇文章主要给大家介绍了关于Python图像处理之二值图像腐蚀的相关资料,对原图进行二值化后,选择不同的结构元素对其进行膨胀和腐蚀运算处理,并仿真出图像结果,需要的朋友可以参考下
    2021-09-09
  • Python读取xlsx文件的实现方法

    Python读取xlsx文件的实现方法

    这篇文章主要介绍了Python读取xlsx文件的实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-07-07
  • Python 实用技巧之利用Shell通配符做字符串匹配

    Python 实用技巧之利用Shell通配符做字符串匹配

    这篇文章主要介绍了Python 实用技巧之利用Shell通配符做字符串匹配的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • Python信息抽取之乱码解决办法

    Python信息抽取之乱码解决办法

    这篇文章主要介绍了Python信息抽取之乱码解决办法的相关资料,需要的朋友可以参考下
    2017-06-06
  • 75条笑死人的知乎神回复,用60行代码就爬完了

    75条笑死人的知乎神回复,用60行代码就爬完了

    这篇文章主要介绍了python爬取知乎回复,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • Python的垃圾回收机制详解

    Python的垃圾回收机制详解

    这篇文章主要介绍了Python的垃圾回收机制详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • pandas pivot_table() 按日期分多列数据的方法

    pandas pivot_table() 按日期分多列数据的方法

    今天小编就为大家分享一篇pandas pivot_table() 按日期分多列数据的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-11-11
  • 详解如何使用python打印出多样字符

    详解如何使用python打印出多样字符

    当你第一次进入Python的世界里,学到的第一句代码是不是print("Hello World"),今天,让我们一起来开启探索print()的奇妙之旅,从最基础的打印字符用法到让它跳舞唱歌——动态显示,让我们一步步解锁print()的各种技能吧,需要的朋友可以参考下
    2024-03-03

最新评论