日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

GraphQL在Django中的使用教程_python

作者:Mr.Lee?jack ? 更新時間: 2023-01-31 編程語言

簡介

特點

  • 請求你所要的數據,不多不少
  • 獲取多個資源,只用一個請求
  • 描述所有的可能,類型系統
  • 幾乎所有語言支持

文檔

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實現,如果返回字段中沒有改要求,將不會深度查詢

原文鏈接:https://blog.csdn.net/xzpdxz/article/details/128436581

欄目分類
最近更新