news 2026/9/10 13:22:24

使用 Django 与 Graphene 构建 GraphQL API:学校管理系统的模型、查询与 Resolver 实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
使用 Django 与 Graphene 构建 GraphQL API:学校管理系统的模型、查询与 Resolver 实战

使用 Django 与 Graphene 构建 GraphQL API:学校管理系统的模型、查询与 Resolver 实战

【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine

本指南以"学校管理系统"为场景,基于 Python + Django + Graphene-Django 从零搭建一个具有学生、教师、课程三层数据关系的 GraphQL API,完整覆盖虚拟环境搭建、ORM 模型与关系设计、DjangoObjectType类型映射、Query/Resolver 实现、GraphiQL 测试等全流程,并延伸讲解当前仓库中 @refinedev/graphql 数据提供器如何消费这类 GraphQL 后端,帮助读者同时掌握"后端如何提供 GraphQL"与"前端如何接入 GraphQL"的完整链路。

为什么选择 GraphQL 承载复杂业务 API

GraphQL 是一种面向数据库通信的查询语言,它的最大价值体现在数据结构复杂、前端只需要请求自己所需字段的场景。与 REST 固定的资源端点不同,GraphQL 采用强类型 Schema 与固定数据结构:

  • 声明式模型让 API 一致且可预测:当后端字段变化时,前端可以借助 Schema 契约提前感知,避免在每次后端变更时同步修改前端代码;
  • 按需取数、降低网络开销:客户端只取自己需要的字段,减少冗余数据传输,从整体上提升系统性能;
  • 聚合多服务数据:在微服务架构中,前端只需调用一个 GraphQL 端点,后端即可在处理、合并、过滤后把来自不同服务的数据一次性返回,从而大幅削减请求次数。

本文将要实现的具体场景是:学校管理系统中有已注册的学生(Student)、教师(Teacher)与课程(Course),课程与教师为一对多关系,课程与学生为多对多关系;我们要通过 GraphQL 一次查询出"课程 + 该课程授课教师 + 该课程全部选课学生"这样的嵌套数据。

前置条件与技术选型

构建 GraphQL API 可以基于多种后端技术栈,最常见的是 Node.js、Python(Flask)与 Python(Django)。本文采用:

组件说明
Python按操作系统从官网下载安装,本文环境为 Windows OS + VS Code + 命令行终端,Python 版本3.12.3
Django作为 Web 框架,提供清晰、务实的工程结构以加速开发,且自带开发用 Web 服务器,无需额外配置
Graphene-Django专门用于在 Django 框架中集成 GraphQL 的官方库

Django 内置了开发服务器,因此不需要像传统方案那样单独搭建 Web 服务器,这让环境准备和联调都更加轻量。

搭建 Django + Graphene 开发环境

创建并激活虚拟环境

在项目目录中打开命令行终端,执行以下命令创建并激活虚拟环境(Windows 环境示例):

python -m venv smsvenv .\smsvenv\Scripts\activate

虚拟环境用于隔离项目依赖,激活后需要在其内部安装 Django 与 Graphene-Django:

pip install django pip install graphene-django

初始化项目与应用

使用 Django 命令行工具创建项目骨架并新建应用:

django-admin startproject school_management cd school_management django-admin startapp school

说明:原教程中django-admin startapp需指定应用名,即django-admin startapp school,这样才能生成名为school的应用目录,用于放置models.pyviews.pyschema.py等文件。

注册应用到 INSTALLED_APPS

打开school_management/settings.py,把graphene_djangoschool两个应用加入INSTALLED_APPS

INSTALLED_APPS = [ # Django 内置应用 "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", # 第三方与业务应用 "graphene_django", "school", ]

至此开发环境搭建完毕,可以开始设计数据模型与 GraphQL API。

数据库设置与模型关系设计

使用 Django 默认的 SQLite 配置

school_management/settings.pyDATABASES配置中,Django 默认提供 SQLite 配置,无需任何额外数据库服务即可运行,适合本教程的开发与学习场景:

DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", "NAME": BASE_DIR / "db.sqlite3", } }

定义 Student、Teacher、Course 三个模型

school/models.py中使用 Django ORM 定义三个模型类,各自包含对应的字段与类型:

from django.db import models class Student(models.Model): name = models.CharField(max_length=100) age = models.IntegerField() class Teacher(models.Model): name = models.CharField(max_length=100) class Course(models.Model): name = models.CharField(max_length=100)

描述模型关系:多对多与一对多

多对多(ManyToMany):每个学生可以选修多门课程,每门课程也可以有多个学生。在Course模型下声明students字段:

class Course(models.Model): name = models.CharField(max_length=100) students = models.ManyToManyField(Student)

一对多(One-to-Many):每门课程只有一位授课教师,但一位教师可以教授多门课程。在Course模型下创建指向Teacher的外键字段:

class Course(models.Model): name = models.CharField(max_length=100) teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE) students = models.ManyToManyField(Student)

最终的整体关系为:Course通过外键关联单个Teacher,通过多对多关联多个StudentTeacherStudent之间不直接关联——这正好对应"查询课程时同时取回教师与选课学生"的嵌套数据需求。

插入示例数据:从迁移到 Django Admin

有多种方式向表中插入示例数据,本文使用 Django Admin 管理界面:

1. 生成并执行数据库迁移:

python manage.py makemigrations python manage.py migrate

2. 创建超级用户:

python manage.py createsuperuser

3. 在school/admin.py中注册模型:

from django.contrib import admin from .models import Student, Teacher, Course admin.site.register(Student) admin.site.register(Teacher) admin.site.register(Course)

4. 启动开发服务器:

python manage.py runserver

5. 浏览器访问管理后台:

http://localhost:8000/admin

6. 使用超级用户登录后,在管理界面分别添加教师、学生与课程数据,并为课程指定授课教师、勾选选课学生。有了这些示例数据,后续的 GraphQL 查询才能返回有意义的嵌套结果。

用 Graphene-Django 实现 GraphQL Schema

Schema 文件的两大组成部分

school/目录下新建schema.py文件,它包含两个主要部分:

  • Types(类型):定义客户端请求的数据结构;
  • Queries + Resolvers(查询与解析器):定义从数据库读取数据(只读操作)的查询。

使用 DjangoObjectType 定义 GraphQL 类型

DjangoObjectType是 Graphene-Django 的核心能力:只需声明Meta.model,它就会依据 Django 模型的字段自动生成对应的 GraphQL 字段,免去手写每个字段的重复工作:

# schema.py import graphene from graphene_django.types import DjangoObjectType from .models import Student, Teacher, Course class StudentType(DjangoObjectType): class Meta: model = Student class TeacherType(DjangoObjectType): class Meta: model = Teacher class CourseType(DjangoObjectType): class Meta: model = Course

CourseType会自动暴露外键teacher与多对多students字段,这正是实现嵌套查询的基础。

定义 Query 与 Resolver 获取嵌套数据

现在用类型去数据库中取数。例如,我们需要获取"教师所授课程及其全部选课学生"的信息,就需要定义一个包含各类型 GraphQL 列表的Query,并为每个列表字段实现对应的 Resolver:

# schema.py import graphene from graphene_django.types import DjangoObjectType from .models import Student, Teacher, Course class StudentType(DjangoObjectType): class Meta: model = Student class TeacherType(DjangoObjectType): class Meta: model = Teacher class CourseType(DjangoObjectType): class Meta: model = Course class Query(graphene.ObjectType): all_students = graphene.List(StudentType) all_teachers = graphene.List(TeacherType) all_courses = graphene.List(CourseType) def resolve_all_students(self, info): return Student.objects.all() def resolve_all_teachers(self, info): return Teacher.objects.all() def resolve_all_courses(self, info): return Course.objects.all() schema = graphene.Schema(query=Query)

注意:Query 仅用于只读操作(如排序、过滤);需要更新数据时必须使用 Mutations(变更操作),这是 GraphQL 对读写职责的明确划分。

创建 GraphQL 视图并注册路由

最后把 GraphQL 接入 Django:在school/views.py中添加视图,将 Schema 与GraphQLView绑定;再在school_management/urls.py中把 URL 映射到该视图,即可通过浏览器访问:

# school/views.py from django.http import JsonResponse from graphene_django.views import GraphQLView from .schema import schema def graphql_view(request): view = GraphQLView.as_view(schema=schema, graphiql=True) return view(request)
# school_management/urls.py from django.contrib import admin from school.views import graphql_view from django.urls import path urlpatterns = [ path("admin/", admin.site.urls), path("graphql/", graphql_view), ]

使用 GraphiQL 测试 API

在上面的graphql_view中传入graphiql=True,Django 就会为/graphql/端点启用 GraphiQL 交互式界面。启动服务器后访问:

http://127.0.0.1:8000/graphql/

在 GraphiQL 左侧输入查询语句,右侧即可看到响应。例如下面的查询会一次性取回每门课程的名称、授课教师姓名,以及所有选课学生的姓名与年龄:

query { allCourses { name teacher { name } students { name age } } }

响应示例:

{ "data": { "allCourses": [ { "name": "Algebra", "teacher": { "name": "Ms. Smith" }, "students": [ { "name": "Alice", "age": 15 }, { "name": "Bob", "age": 16 } ] } ] } }

GraphiQL 还自带文档面板与自动补全,可以直接观察QueryStudentTypeTeacherTypeCourseType暴露的全部字段,非常便于验证 Schema 设计与实际返回结构。除了 GraphiQL,也可以使用 Postman 等工具以 HTTP POST 方式发送 GraphQL 查询。

前端如何消费这类 GraphQL API:refine 的 @refinedev/graphql

完成后端 GraphQL API 之后,前端接入是另一大关键环节。当前仓库中的 packages/graphql 包(@refinedev/graphql,见 package.json)为 Refine 提供了 GraphQL 数据提供器与实时提供器,让 React 应用可以直接消费上文这类 Django/Graphene 后端。

用 urql Client 创建数据提供器

数据提供器的工厂函数位于 dataProvider/index.ts。其创建方式以 urqlClient为核心参数(示例参见 examples/data-provider-graphql/src/App.tsx):

import { Client, fetchExchange } from "@urql/core"; import createDataProvider, { createLiveProvider } from "@refinedev/graphql"; import { createClient } from "graphql-ws"; const API_URL = "https://api.nestjs-query.refine.dev/graphql"; const WS_URL = "wss://api.nestjs-query.refine.dev/graphql"; export const client = new Client({ url: API_URL, exchanges: [fetchExchange], }); // 在 Refine 中注册 <Refine dataProvider={createDataProvider(client)} liveProvider={createLiveProvider(createClient({ url: WS_URL }))} ... />

按操作定制的 dataMapper 与 buildVariables

dataProvider/options.ts 中定义了GraphQLDataProviderOptions,允许为createcreateManygetOnegetListgetManyupdateupdateManydeleteOnedeleteManycustom每个操作单独定制两件事:

  • buildVariables:把 Refine 的查询参数(如idvariablespaginationsortersfiltersmeta.gqlVariables)转换成 GraphQL 操作变量。例如getOne.buildVariables返回{ id: params.id, ...params.meta?.gqlVariables }update.buildVariables返回{ input: { id, update: params.variables } }
  • dataMapper:从响应中提取目标数据,并依赖camelcasepluralize按资源名推断响应键(如updateOnePostall_风格命名)。

这与你用 Graphene 后端时的操作命名约定密切相关:GraphQL 操作的名称(如allCoursesupdateOneCourse)与资源命名方式,需要与dataMapper默认推断规则或自定义meta保持一致,前后端才能正确对接。

内置的分页、排序与过滤

在 utils/getListHelpers.ts 中实现了将 Refine 通用参数翻译为 GraphQL 变量的逻辑:

  • buildPagination:把{ pageSize, currentPage }转为{ limit, offset },分页关闭时返回{ limit: 2147483647 }
  • buildSorters:把排序字段与方向转为{ field, direction }
  • buildFilters:维护了一张运算符映射表,例如eq → eqne → neqnin → notIncontains → iLikebetween → between等,并支持and/or组合过滤。

用 liveProvider 订阅数据变更

liveProvider/index.ts 中的createLiveProvider基于graphql-ws提供实时能力:useList场景会同时订阅createdupdateddeleted三类事件,useOne场景订阅updated事件。这与 GraphQL 后端的 Subscriptions 能力相对应——如果你的 Django 后端需要实时推送,可以参考同样的订阅模式进行扩展。

总结

本文以学校管理系统为完整案例,走通了从 GraphQL 概念、Python/Django 环境搭建、ORM 模型与关系建模、示例数据录入,到 Graphene-Django 的DjangoObjectType类型定义、Query/Resolver 实现、视图与路由注册,以及 GraphiQL 实测的端到端流程。GraphQL 最适合在"API 需要被不同客户端以特定数据结构集成"或"客户端只需要少量特定字段、追求高性能与低带宽占用"的场景中发挥价值;理解 Schema、Type、Query 与 Mutation 的分工后,再配合 Refine 生态的 @refinedev/graphql 数据提供器,就能把 Django + Graphene 构建的后端能力无缝接入 React 前端应用,形成一套完整、可复用的全栈 CRUD 与实时数据方案。

【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 13:18:27

Quick Summary Skill

Quick Summary Skill 【免费下载链接】AionUi Open-source 24/7 Cowork app for OpenClaw, Hermes, Claude Code, Codex, OpenCode and 20 more CLI Agent | Customize your assistants | Team them up&#xff5c;Star if you like it! 项目地址: https://gitcode.com/GitHu…

作者头像 李华
网站建设 2026/9/10 13:17:49

CANN/ge销毁执行配置句柄API

aclmdlDestroyExecConfigHandle 【免费下载链接】ge GE&#xff08;Graph Engine&#xff09;是面向昇腾的图编译器和执行器&#xff0c;提供了计算图优化、多流并行、内存复用和模型下沉等技术手段&#xff0c;加速模型执行效率&#xff0c;减少模型内存占用。 GE 提供对 PyTo…

作者头像 李华
网站建设 2026/9/10 13:13:37

STM32+RM500U+AHT20温湿度上云实战:工业级可靠通信与TCP数据上报

简介&#xff1a;这是一套面向嵌入式物联网开发者的STM32实战项目资源&#xff0c;聚焦5G通信与环境传感融合应用&#xff0c;适用于具备C语言基础和HAL库开发经验的中级单片机学习者及工程师。项目以移远RM500U 5G模块为核心&#xff0c;完整实现AHT20温湿度数据采集、TCP协议…

作者头像 李华