GraphQL在Django中的使用

news2024/11/25 16:29:50

简介

特点

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

谁在用

在这里插入图片描述

文档

  • 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实现,如果返回字段中没有改要求,将不会深度查询

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/114367.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WordPress 添加百度主动推送代码,加速网站收录保护原创文章

WordPress是世界上使用人数最多开源程序之一&#xff0c;它的优点有很多&#xff0c;譬如&#xff0c;简单易用、样式丰富&#xff0c;模板众多&#xff0c;安全性能高&#xff0c;对搜索引擎友好&#xff0c;收录快、扩展性强&#xff0c;功能强大等等&#xff0c;其中我最喜欢…

JVM的类加载机制

一、类加载机制 类的加载指的是将类的.class文件中的二进制数据读入到内存中&#xff0c;将其放在运行时数据区的方法区内****&#xff0c;然后在堆区创建一个java.lang.Class对象&#xff0c;用来封装类在方法区内的数据结构。类的加载的最终产品是位于堆区中的Class对象&…

六、应用层(三)文件传输协议(FTP)

将某台计算机中的文件通过网络传送到可能相距很远的另一台计算机中&#xff0c;是一项基本的网络应用&#xff0c;即文件传送。 文件传送协议FTP&#xff08;File Transfer Protocal&#xff09;是因特网上使用得最广泛的文件传送协议。 FTP提供交互式的访问&#xff0c;允许…

欢祝圣诞——北斗星的爱!

2022年圣诞节到来啦&#xff0c;很高兴这次我们又能一起度过~ ★★给大家推荐两首我很喜欢的歌曲&#xff0c;第一首是标题同名歌曲&#xff1a;1.张杰的《北斗星的爱》&#xff1b;另一首是&#xff1a;2.张杰的《星星》&#xff0c;这两首歌真的很震撼很好听&#xff01; 我…

2022细胞生物学实验原理复习资料汇总

2022细胞生物学实验原理复习资料汇总1.2022年考试复习题及参考答案2.2021年考试复习题及参考答案3.2020年之前考试复习题汇总4.复习重点&#xff08;汇总&#xff09;5.排版好的PDF高清版 获取途径&#xff08;资源2021年版&#xff0c;链接2022年最新版本&#xff09;1.2022年…

Linux网络编程之epoll多路转接服务器

Linux网络编程之epoll多路转接服务器 一、epoll的基本概念 epoll是Linux下多路复用IO接口select/poll的增强版本&#xff0c;它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率&#xff0c;因为它会复用文件描述符集合来传递结果而不用迫使开发者每次等待…

基于自动模糊聚类的图像分割研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

kubernetes之数据存储详解

目录 一、存储卷的作用 二、数据卷概述 三、数据卷emptyDir 四、数据卷hostPath 五、数据卷&#xff1a;NFS 六、持久卷概述 6.1PV静态供给 6.2PV 动态供给(StorageClass) 6.3 PV 生命周期 6.3.1 ACCESS MODES (访问模式) 6.3.2 RECLAIM POLICY (回收策略) 6.3.3 S…

【Redis场景2】缓存更新策略(双写一致)

在业务初始阶段&#xff0c;流量很少的情况下&#xff0c;通过直接操作数据是可行的操作&#xff0c;但是随着业务量的增长&#xff0c;用户的访问量也随之增加&#xff0c;在该阶段自然需要使用一些手段(缓存)来减轻数据库的压力&#xff1b;所谓遇事不决&#xff0c;那就加一…

vue 基础入门:vue 的调试工具

1. 安装 vue-devtools 调试工具 vue 官方提供的 vue-devtools 调试工具&#xff0c;能够方便开发者对 vue 项目进行调试与开发。 Chrome 浏览器在线安装 vue-devtools &#xff1a;https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajb…

六、应用层(五)万维网(www)

目录 5.1 WWW的概念与组成结构 5.2 超文本传输协议&#xff08;HTTP&#xff09; 5.2.1 HTTP的操作过程 5.2.2 HTTP的特点 5.2.3 HTTP的报文结构 5.1 WWW的概念与组成结构 万维WWW&#xff08;World Wide Web&#xff09;简称web并非某种特殊的计算机网络。它…

商城管理系统

商城管理系统 文章目录商城管理系统要求&#xff1a;项目结构图AddProductServlet添加商品&#xff1a;AddToCart将商品添加至购物车ClearCart清空购物车DeleteProductServlet删除商品EditProductServlet修改商品FindProductServlet查找商品LoginServlet登录ProductControl商品…

初级C语言之【数组】

&#x1f996;作者&#xff1a;学写代码的恐龙 &#x1f996;博客主页&#xff1a;学写代码的恐龙博客主页 &#x1f996;专栏&#xff1a;【初级c语言】 &#x1f996;语录&#xff1a;❀未来的你&#xff0c;一定会感谢现在努力奋斗的自己❀ 初级C语言之【数组】一&#xff…

Swagger在线API文档

Swagger 解决的问题 随着互联网技术的发展&#xff0c;现在的网站架构基本都由原来的后端渲染&#xff0c;变成了前后端分离的形态&#xff0c;而且前端技术和后端技术在各自的道路上越走越远。前端和后端的唯一联系&#xff0c;变成了 API 接口&#xff0c;所以 API 文档变成…

C++进阶---C++11

本篇主要是介绍C11中新添加的一些特性。 文章目录 1.C11简介2.列表初始化3.变量类型推导4.新增容器---静态数组array5.右值引用6.lambda表达式7.包装器8.新的类功能9.可变参数模板一、C11简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)&#xff0c;使得C03这个名字…

Python高阶函数装饰器

“ 从CANoe vTESTstudio版本7开始&#xff0c;支持使用python编辑器编写python脚本。其中CANoe提供了许多API接口给python使用&#xff0c;大大扩展了python的可用性。在python中使用装饰器定义capl中的事件处理程序&#xff08;on key/on timer等&#xff09;。对此我们有必要…

C语言—宏定义

宏定义的作用是替换&#xff0c;再复杂也只能替换&#xff0c;不能用做计算&#xff1b; 一个源文件将另一个源文件的全部内容包含进来&#xff1b; 条件编译&#xff1b; 不带参数的宏定义&#xff1a; #include <stdio.h> #define PI 3.14int main() {printf("…

聊聊Redis消息队列-实现异步秒杀

一、前言 消息队列&#xff08;Message Queue&#xff09;, 字面意思就是存放消息的队列&#xff0c;最简单的消息队列模型包括3个角色&#xff1a; 消息队列&#xff1a;存储和管理消息&#xff0c;也被称为消息代理&#xff08;Message Broker&#xff09;;生产者&#xff…

Shell编程补充

Shell编程补充shell的变量定义变量的单双引号的不同输出变量父子shellshell子串BASHshell子串的用法shell统计变量长度输出程序运行时间结论:shell扩展变量用于处理变量值的创建子shell(进程列表)查看是否开启子shell在运行内置命令,外置命令shell编程总结shell的变量 定义变量…

小黑实习debug中遇到了函数式编程的混乱,特此进行的日常积累:python函数积累1

函数参数中有默认值&#xff0c;在函数内部会创建一块区域并维护这个默认值 # 在函数内存中会维护一块区域存储 [1,2,666,666,666] 100010001 def func(a1,a2[]):a2.append(666)print(a1,a2)func(100) func(1000)100 [666] 1000 [666, 666] def func(a1,a2[]):a2.append(666…