当前位置: 首页 > news >正文

四、【API 开发篇 (上)】:使用 Django REST Framework 构建项目与模块 CRUD API

【API 开发篇 】:使用 Django REST Framework 构建项目与模块 CRUD API

    • 前言
      • 为什么选择 Django REST Framework (DRF)?
      • 第一步:创建 Serializers (序列化器)
      • 第二步:创建 ViewSets (视图集)
      • 第三步:配置 URLs (路由)
      • 第四步:在项目 URLconf 中包含 App 的 URLs
      • 第五步:测试 API
    • 总结

前言

还记得我们的架构蓝图吗?

  • 前端 (Vue3) 负责展示和交互。
  • 后端 API (DRF) 是前后端沟通的桥梁。
  • 后端逻辑 (Django) 处理业务和数据。
  • 数据持久层 (Models/Database) 存储数据。

今天,我们的重点就是构建中间的“桥梁”——后端 API 层。

为什么选择 Django REST Framework (DRF)?

在 Django 生态系统中,DRF 是构建 RESTful API 的标准。它提供了一系列强大的工具,可以极大地加速 API 的开发过程:

  • Serializers (序列化器): 轻松地将复杂的 Django 模型对象转换成 JSON/XML 等格式(用于响应前端),或将接收到的数据反序列化并验证(用于创建或更新数据)。
  • Views / ViewSets (视图/视图集): 处理请求和响应。ViewSets 特别方便,可以将多个相关的视图逻辑(如列表、详情、创建、更新、删除)合并到一个类中。
  • Routers (路由): 自动生成 URL 模式,省去了手动编写大量 URLconf 的麻烦。
  • Authentication & Permissions (认证和权限): 提供了多种认证和权限机制,方便保护你的 API。
  • Browsable API (可浏览的 API): DRF 提供了一个非常友好的网页界面,可以直接在浏览器中测试 API,对于开发和调试非常有用。

第一步:创建 Serializers (序列化器)

Serializers 负责数据的进出转换。我们需要为 ProjectModule 模型创建对应的序列化器。

api 文件夹下,创建一个新文件 serializers.py
在这里插入图片描述

打开 api/serializers.py,添加以下代码:
在这里插入图片描述

# test-platform/api/serializers.pyfrom rest_framework import serializers
from .models import Project, Module, TestCase # 导入你之前定义的模型class ProjectSerializer(serializers.ModelSerializer):"""项目序列化器"""class Meta:model = Project # 指明要序列化的模型fields = '__all__' # 序列化模型中的所有字段class ModuleSerializer(serializers.ModelSerializer):"""模块序列化器"""class Meta:model = Module # 指明要序列化的模型# 明确指定需要序列化的字段,包括外键 project# 注意:默认情况下,ModelSerializer 序列化外键时只会包含关联对象的 IDfields = ['id', 'name', 'description', 'project', 'create_time', 'update_time']# 也可以用 '__all__', 但明确指定有助于理解# fields = '__all__'

代码解释:

  • from rest_framework import serializers: 导入 DRF 的序列化器模块。
  • from .models import ...: 导入我们在 models.py 中定义的模型。
  • class ProjectSerializer(serializers.ModelSerializer):: 定义一个名为 ProjectSerializer 的类,它继承自 serializers.ModelSerializerModelSerializer 是 DRF 提供的一个便捷类,可以根据 Django 模型自动生成序列化器的字段。
  • class Meta:: 在序列化器类内部定义一个 Meta 类,用于配置序列化器。
  • model = Project: 指明这个序列化器是为哪个模型服务的。
  • fields = '__all__': 表示序列化该模型的所有字段。你也可以使用一个列表来指定需要序列化的字段,例如 fields = ['id', 'name', 'owner']。对于 ModuleSerializer,我们明确列出了字段,包括了 project 外键字段。当序列化时,DRF 默认会显示外键关联对象的 ID。

第二步:创建 ViewSets (视图集)

ViewSets 负责处理 HTTP 请求,调用序列化器进行数据转换,并与数据库交互。使用 ModelViewSet 可以非常快速地实现 CRUD 操作。

打开 api/views.py 文件,添加以下代码:
在这里插入图片描述

# test-platform/api/views.py# from django.shortcuts import render # 这个现在用不到了
from rest_framework import viewsets
from .models import Project, Module, TestCase # 导入模型
from .serializers import ProjectSerializer, ModuleSerializer # 导入序列化器class ProjectViewSet(viewsets.ModelViewSet):"""项目管理视图集提供项目列表、创建、详情、更新、删除等接口"""queryset = Project.objects.all() # 指定视图集查询的数据集serializer_class = ProjectSerializer # 指定用于序列化和反序列化的序列化器class ModuleViewSet(viewsets.ModelViewSet):"""模块管理视图集提供模块列表、创建、详情、更新、删除等接口"""queryset = Module.objects.all() # 指定视图集查询的数据集serializer_class = ModuleSerializer # 指定用于序列化和反序列化的序列化器# TestCaseViewSet 将在下一篇文章中实现,因为它涉及更复杂的序列化和逻辑
# class TestCaseViewSet(viewsets.ModelViewSet):
#     queryset = TestCase.objects.all()
#     serializer_class = TestCaseSerializer

代码解释:

  • from rest_framework import viewsets: 导入 DRF 的视图集模块。
  • from .models import ...from .serializers import ...: 导入相关的模型和序列化器。
  • class ProjectViewSet(viewsets.ModelViewSet):: 定义一个 ProjectViewSet,继承自 viewsets.ModelViewSet
  • queryset = Project.objects.all(): 这是 ModelViewSet 所需的关键属性之一。它指定了该视图集将操作哪些数据集合。这里是所有的 Project 对象。DRF 会根据这个 queryset 来执行列表、详情等操作。
  • serializer_class = ProjectSerializer: 这是 ModelViewSet 所需的另一个关键属性。它指定了该视图集使用哪个序列化器来进行数据的输入验证和输出格式化。
  • ModelViewSet 会自动为我们生成以下路由和对应的操作:
    • GET /projects/: 获取项目列表 (list action)
    • POST /projects/: 创建新项目 (create action)
    • GET /projects/{id}/: 获取指定 ID 的项目详情 (retrieve action)
    • PUT /projects/{id}/: 更新指定 ID 的项目 (update action)
    • PATCH /projects/{id}/: 部分更新指定 ID 的项目 (partial_update action)
    • DELETE /projects/{id}/: 删除指定 ID 的项目 (destroy action)

ModuleViewSet 的原理和 ProjectViewSet 完全一样,只是操作的对象变成了 Module 模型和 ModuleSerializer

第三步:配置 URLs (路由)

DRF 的 Routers 可以自动帮我们生成 ModelViewSet 对应的 URL 模式。

api 文件夹下,创建一个新文件 urls.py
在这里插入图片描述

打开 api/urls.py,添加以下代码:
在这里插入图片描述

# test-platform/api/urls.pyfrom django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import ProjectViewSet, ModuleViewSet # 导入视图集# 创建一个 DefaultRouter 实例
router = DefaultRouter()# 注册视图集
# 第一个参数是 URL 前缀,例如 'projects'
# 第二个参数是视图集类
# 第三个参数是可选的 basename,用于生成 URL 名称,通常与 URL 前缀一致
router.register(r'projects', ProjectViewSet, basename='project')
router.register(r'modules', ModuleViewSet, basename='module')# router.urls 会自动生成包含所有注册的 ViewSet 对应的 URL 模式列表
urlpatterns = [path('', include(router.urls)), # 将 router 生成的 URL 模式包含进来
]

代码解释:

  • from rest_framework.routers import DefaultRouter: 导入 DRF 的默认路由类。
  • from .views import ...: 导入我们刚刚创建的视图集。
  • router = DefaultRouter(): 创建一个路由器实例。DefaultRouter 会自动包含根视图(显示所有注册的 API 列表)和格式后缀模式。
  • router.register(r'projects', ProjectViewSet, basename='project'): 注册 ProjectViewSet。访问路径会以 /projects/ 开头。例如 /projects/ (列表/创建), /projects/1/ (详情/更新/删除 ID 为 1 的项目)。
  • router.register(r'modules', ModuleViewSet, basename='module'): 注册 ModuleViewSet,访问路径以 /modules/ 开头。
  • urlpatterns = [...]: 定义 URL 模式列表。
  • path('', include(router.urls)): 这一行将路由器自动生成的 URL 模式全部包含进 api 应用的 URLconf 中。因为我们将这个 include 的第一个参数设为 '',所以视图集注册时的 URL 前缀(如 projects, modules)会直接跟在应用 URL(例如 api/,我们稍后会在项目 urls.py 中配置)后面。

第四步:在项目 URLconf 中包含 App 的 URLs

最后一步,我们需要在整个 Django 项目的 URL 配置文件 (backend/urls.py) 中,包含我们 api App 的 URL 模式。

打开 test-platform/backend/urls.py 文件:
在这里插入图片描述

# test-platform/backend/urls.pyfrom django.contrib import admin
from django.urls import path, include # 确保导入了 includeurlpatterns = [path('admin/', admin.site.urls), # Django Admin 的 URLpath('api/', include('api.urls')), # 添加这一行,将所有以 'api/' 开头的请求转发到 api.urls 处理
]

代码解释:

  • from django.urls import path, include: 确保导入了 include 函数。
  • path('api/', include('api.urls')): 这一行是关键。它告诉 Django,任何以 api/ 开头的 URL 请求都应该“包含”并交给 api 应用下的 urls.py 文件去处理。
  • 结合 api/urls.py 中的 path('', include(router.urls)),最终的完整 URL 路径会是 /api/projects/, /api/modules/ 等。

第五步:测试 API

后端 API 已经基本搭建好了,现在来验证一下。

  1. 启动 Django 开发服务器:
    在终端中 (确保在 test-platform 目录下,并且 (venv) 已激活),运行:

    python manage.py runserver
    

    在这里插入图片描述

  2. 访问 DRF 的可浏览 API 界面:
    在浏览器中访问 http://127.0.0.1:8000/api/
    在这里插入图片描述

    如果看到以上页面内容,说明 DRF 和路由配置成功了。这个页面是 DefaultRouter 提供的根视图,列出了所有注册的 API 终端 (projects/modules/)。

  3. 测试 Project API:
    点击 http://127.0.0.1:8000/api/projects/ 链接。
    在这里插入图片描述

    • GET (列表): 你会看到一个获取项目列表的页面。如果之前你在 Django Admin 中创建过项目,这里会显示出来。页面下方有一个表单,可以用来发送 POST 请求创建新项目。
      在这里插入图片描述
      在这里插入图片描述

    • POST (创建): 在页面下方的表单中填写项目信息(名称, 描述, 负责人, 项目状态),然后点击 POST 按钮。如果成功,会返回新创建的项目数据,并在上方列表中刷新显示。
      在这里插入图片描述
      在这里插入图片描述

    • GET (详情): 在项目列表页面,点击某个项目的 URL (例如 http://127.0.0.1:8000/api/projects/1/),可以查看该项目的详情。
      在这里插入图片描述

    • PUT/PATCH/DELETE: 在项目详情页面,也会有 PUT (完全更新), PATCH (部分更新) 和 DELETE 的表单或按钮,你可以尝试修改或删除项目。

  4. 测试 Module API:
    返回 http://127.0.0.1:8000/api/,点击 http://127.0.0.1:8000/api/modules/ 链接。
    在这里插入图片描述

    • GET (列表): 查看模块列表。
    • POST (创建): 创建模块时,请注意表单中会有 project 字段。你需要填写该模块所属项目的 ID。例如,如果你创建的第一个项目 ID 是 1,那么这里就填写 1。填写其他模块信息(name, description),然后 POST。
    • 测试详情、更新、删除操作与 Project 类似。
      在这里插入图片描述

通过可浏览的 API 界面,你可以在不写任何前端代码的情况下,方便地验证你的后端 API 是否按照预期工作。

总结

你已经成功地迈出了后端 API 开发的关键一步:

  • ✅ 理解了 DRF 在构建 API 中的作用和核心组件 (Serializers, ViewSets, Routers)。
  • ✅ 为 ProjectModule 模型创建了 ModelSerializer
  • ✅ 使用 ModelViewSet 快速实现了 ProjectModule 的 CRUD 视图逻辑。
  • ✅ 利用 DefaultRouter 自动生成了 API 的 URL 模式。
  • ✅ 在项目 URL 配置中包含了 API App 的 URL。
  • ✅ 通过 DRF 的可浏览 API 界面验证了你的 API 功能。

现在,你的后端已经能够响应前端对项目和模块数据的操作请求了。

在下一篇文章中,我们将继续 API 开发,但会处理稍微复杂一些的 测试用例 (TestCase) 模型。

相关文章:

四、【API 开发篇 (上)】:使用 Django REST Framework 构建项目与模块 CRUD API

【API 开发篇 】:使用 Django REST Framework 构建项目与模块 CRUD API 前言为什么选择 Django REST Framework (DRF)?第一步:创建 Serializers (序列化器)第二步:创建 ViewSets (视图集)第三步:配置 URLs (路由)第四步…...

vscode连接本地Ubuntu

因为在学习项目的时候,自己的云服务器性能太差一直要编译很长时间,而且总是连接失败,所以搞了一个Ubuntu25.04的系统在自己的vmare中。 其中参考了以下文章。 Ubuntu 24.04 桌面版安装指南(2025版) | 官网镜像下载启动盘制作保姆级图文教程…...

idea无法识别Maven项目

把.mvn相关都删除了 导致Idea无法识别maven项目 或者 添加导入各个模块 最后把父模块也要导入...

Redis应用--缓存

目录 一、什么是缓存 1.1 二八定律 二、使用Redis作为缓存 三、缓存的更新策略 3.1 定期更新 3.2 实时生成 四、缓存预热、缓存穿透、缓存雪崩和缓存击穿 4.1 缓存预热 4.2 缓存穿透 4.3 缓存雪崩 4.4 缓存击穿 一、什么是缓存 缓存(cache)是计算机的一个经典的概念…...

大语言模型与人工智能:技术演进、生态重构与未来挑战

目录 技术演进:从专用AI到通用智能的跃迁核心能力:LLM如何重构AI技术栈应用场景:垂直领域的技术革命生态关系:LLM与AI技术矩阵的协同演进挑战局限:智能天花板与伦理困境未来趋势:从语言理解到世界模型1. 技术演进:从专用AI到通用智能的跃迁 1.1 三次技术浪潮的跨越 #me…...

多模态大语言模型arxiv论文略读(八十六)

EVALALIGN: Supervised Fine-Tuning Multimodal LLMs with Human-Aligned Data for Evaluating Text-to-Image Models ➡️ 论文标题:EVALALIGN: Supervised Fine-Tuning Multimodal LLMs with Human-Aligned Data for Evaluating Text-to-Image Models ➡️ 论文作…...

C++--string类对象

一,引言 string类对象在于更好的处理字符串问题,为对于字符串这一类型提供更加方便的接口和运算符的重载。本片文章首先会引入auto关键字和范围for两个C11小语法。之后按照如下网站所提供的顺序经行讲解。cplusplus.com - The C Resources Networkhttps://legacy.c…...

云计算与大数据进阶 | 28、存储系统如何突破容量天花板?可扩展架构的核心技术与实践—— 分布式、弹性扩展、高可用的底层逻辑(下)

在上篇中,我们围绕存储系统可扩展架构详细探讨了基础技术原理与典型实践。然而,在实际应用场景中,存储系统面临的挑战远不止于此。随着数据规模呈指数级增长,业务需求日益复杂多变,存储系统还需不断优化升级&#xff0…...

Python _day31

DAY 31 文件的规范拆分和写法 今日的示例代码包含2个部分 notebook文件夹内的ipynb文件,介绍下今天的思路项目文件夹中其他部分:拆分后的信贷项目,学习下如何拆分的,未来你看到的很多大项目都是类似的拆分方法 知识点回顾 规范的文…...

【JavaWeb】MyBatis

1 介绍 什么是MyBatis? MyBatis是一款优秀的 持久层 框架,用于简化JDBC的开发。 MyBatis本是 Apache的一个开源项目iBatis,2010年这个项目由apache迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。 MyBatis官网https://my…...

vue2实现【瀑布流布局】

瀑布流 1. 解释2. 形成结构和样式3. 自定义指令 1. 解释 瀑布流特征: 等宽不等高:元素宽度固定,高度根据内容自适应。错落排列:元素像瀑布一样从上到下依次填充,自动寻找最短列插入 体现:图中第一排1&…...

系统架构设计(十六):敏感点、权衡点、风险点和非风险点

术语定义 概念定义说明敏感点(Sensitivity Point)架构设计中对某个质量属性有显著影响的点,一旦改变该点,会显著影响系统的某个质量属性。风险点(Risk Point)由于架构决策带来的潜在失败风险,可…...

优化dp贪心数论

这次三个题目都来自牛客周赛93,个人觉得出的很好,收获颇多。 1.简单贪心 题目意思: 任意选定两个数字,相加之和替代两个数字中的一个,另一个抹除。求操作之后最大字典序之和 思路: 最大字典序之和&…...

详解MySQL 的 binlog,redo log,undo log

MySQL 的 binlog、redo log 和 undo log 是数据库事务处理与数据一致性的核心组件,各自承担不同的职责。 1. binlog(二进制日志) 定位:MySQL Server 层实现的逻辑日志,与存储引擎无关。作用: 主从复制&…...

SymPy|主元、重新表示、分数、约分表达式、极限、级数、ode、获取值、输出形式

SymPy 是一个 Python 的符号计算库,广泛应用于数学计算、物理建模、工程分析等领域。本文将详细介绍 SymPy 在处理主元操作、重新表示、分数、约分表达式、极限、级数、常微分方程(ODE)以及获取值和输出形式等方面的应用,通过完整…...

Java 05正则表达式

正则表达式 1.简介 一个字符串,指定一些规则,来校验其他的字符串 String s"";规则 需要进行匹配的字符串.matches(s);来判断2.字符类**(单个) [abc] String s"[ABC]"; "A".matches(s);返回true…...

IEEE 802.1Q协议下封装的VLAN数据帧格式

1.概要 802.1d定义了生成树 802.1w定义了快速生成树 802.1s定义了多生成树 802.1q定义了VLAN 2.说明 IEEE802.1q协议的作用是(生成VLAN标记)VLAN编号取值范围:0-4095,其中0和4095是保留编号,所最大值是&#xff…...

VMware三种网络配置对比

​桥接模式(Bridged Mode)​​ ​​核心特点​​: 虚拟机被视为局域网中的独立设备,直接使用物理网络适配器,需配置与宿主机同一网段的IP地址。 ​​典型场景​​: 虚拟机需对外提供服务(如Web…...

再来1章linux系列-19 防火墙 iptables 双网卡主机的内核 firewall-cmd firewalld的高级规则

学习目标: 实验实验需求实验配置内容和分析 (每一个设备的每一步操作)实验结果验证其他 学习内容: 实验实验需求实验配置内容和分析 (每一个设备的每一步操作)实验结果验证其他 1.实验 2.实验需求 图…...

Word 转 HTML API 接口

Word 转 HTML API 接口 图像/转换 Word 文档转换为 HTML 文件转换 / 超高精度与还原度 文件转换 / Word。 1. 产品功能 超高精度与还原度的 HTML 文件转换;支持将 Word 文档转换为 HTML 格式;支持 .doc 和 .docx 格式;保持原始 Word 文档的…...

深入解析MATLAB codegen生成MEX文件的原理与优势

一、MATLAB codegen底层工作机制 1.1 MATLAB执行引擎的局限性 MATLAB作为解释型语言,其执行过程包含多个关键步骤: 语法解析:将.m文件代码转换为抽象语法树(AST) 类型推断:运行时动态确定变量类型 内存管理:自动处…...

PEFT简介及微调大模型DeepSeek-R1-Distill-Qwen-1.5B

🤗 PEFT(参数高效微调)是由Huggingface团队开发的开源框架,专为大型预训练模型(如GPT、LLaMA、T5等)设计,用于高效地将大型预训练模型适配到各种下游应用,而无需对模型的所有参数进行…...

Python训练营打卡 Day31

文件的规范拆分和写法 今日的示例代码包含2个部分 notebook文件夹内的ipynb文件,介绍下今天的思路项目文件夹中其他部分:拆分后的信贷项目,学习下如何拆分的,未来你看到的很多大项目都是类似的拆分方法 知识点回顾:文件…...

Google精准狙击OpenAI Codex,发布AI编程助手Jules!

自从OpenAI推出 Codex之后,Google就憋不住了,悄悄得瞄准了OpenAI的最新成果。 原计划是是打算在明天举行的Google I/O年度开发者大会上发布相关产品,但Google似乎已经一刻也等不了了。 就在昨天,谷歌正式推出了其AI编程——Ju…...

【办公类-18-04】(Python)“验血单信息”批量生成打印(学校、班级、姓名、性别)

背景说明 督导结束了,准备春游(夏游),搭档在给孩子写打卡单、心愿单,感慨“好多字都不会写了!” 此时,保健老师来发体检材料,叮嘱红色验血单的填写方法。 我觉得我的字也是一塌糊涂。我想用以前做“毕业证书”的方式,将班级幼儿信息打印在体检单上。 【办公类-18-03…...

如何使用通义灵码提高前端开发效率

工欲善其事,必先利其器。对于前端开发而言,使用VSCode已经能够极大地提高前端的开发效率了。但有了AI加持后,前端开发的效率又更上一层楼了! 本文采用的AI是通义灵码插件提供的通义千问大模型,是目前AI性能榜第一梯队…...

苍穹外卖04 新增菜品菜品分页查询删除菜品修改菜品

2-6 新增菜品 02 05-新增菜品_需求分析和设计 03 06-新增菜品_代码开发_1 文件上传接口开发: 在这一部分我们主要在于对阿里云oss的代码开发和实现 1.配置阿里云oss: alioss:endpoint: oss-cn-beijing-internal.aliyuncs.comaccess-key-id: access-ke…...

C++ 读取英伟达显卡名称、架构及算力

C++ 读取英伟达显卡名称、架构及算力 通过CUDA Runtime API获取计算能力(推荐)​​CUDA计算能力(Compute Capability)的版本号直接对应显卡架构(如8.6=Ampere,9.0=Hopper)。实现步骤: ​​1.安装依赖​​: 安装 NVIDIA CUDA Toolkit。确保显卡驱动支持CUDA。2. ​​C…...

VitePress 中以中文字符结尾的字体加粗 Markdown 格式无法解析

背景 在编写vitepress项目过程中,发现了一个markdown格式解析的问题。 md文件中,以中文句号结尾的字体加粗,无法正确解析: 不只是中文句号,只要是加粗语句中以中文字符结尾,都无法被正确解析 需要将中文…...

2.前端汇总

框架 html5 html语法 css css3 css语法 框架 tailwind css 官网 JavaScript JavaScript语法 typescript 语法 nodejs 语法 vue3 官网 组件 vite 打包 vue router -路由 pinia - 状态管理 ui element plus axios - ajax 后台管理系统前端快速开发框架 …...

外部因素导致的 ADC误差来源分析

前面分享了ADC自身因素带来的误差,现在再分享一波由于外部因素导致的ADC采样误差。 一、模拟信号源输入减少带来的误差 看一个STM32的ADC转换器的示意图: 从图中可以看到,输入源与采样引脚之间存在阻抗RAIN,流入引脚的电压可能因…...

集成运算放大器知识汇总

一、集成运放的组成 集成运算放大器,就是通过内部元器件的电参量关系将电参量进行运算,达到放大的目的。我们拆解来看: 集成:将电路封装,留出接口,使其模块化,便于移植。运算:这里…...

HBCPC2025 补题 (F、I)

HBCPC2025 补题 补题连接:Codeforces I 感染 做法1&#xff1a;std做法&#xff1a;树上dp统计贡献找最大 #include <bits/stdc.h> using namespace std; typedef long long ll; #define endl \n #define int long long #define pb push_back #define pii pair<int,…...

针对 CSDN高质量博文发布 的详细指南

结合技术写作规范与平台特性&#xff0c;分为 内容规划、写作技巧、排版优化、发布策略 四部分&#xff0c;确保专业性与传播效果&#xff1a; 一、内容规划&#xff1a;精准定位与深度挖掘 选题策略 热点结合&#xff1a;追踪技术趋势&#xff08;如2025年AIGC、量子计算&am…...

python读写bin文件

import numpy as np# 创建二进制数据 data np.array([0x33, 0x34, 0x35, 0x36], dtypenp.uint8)# 写入bin文件 with open(example.bin, wb) as f:data.tofile(f)print("bin文件生成成功")data np.fromfile(example.bin, dtypenp.uint8) print("numpy读取结果:…...

矩阵的秩(Rank)

矩阵的秩&#xff08;Rank&#xff09;是线性代数中的核心概念&#xff0c;表示矩阵中线性无关的行&#xff08;或列&#xff09;的最大数量&#xff0c;反映了矩阵所包含的“独立信息”的多少。以下是其核心要点&#xff1a; 1. 秩的定义 行秩&#xff1a;矩阵中线性无关的行…...

Vue响应式系统演进与实现解析

一、Vue 2 响应式实现详解 1. 核心代码实现 // 依赖收集器&#xff08;观察者模式&#xff09; class Dep {constructor() {this.subscribers new Set();}depend() {if (activeEffect) {this.subscribers.add(activeEffect);}}notify() {this.subscribers.forEach(effect &g…...

【SPIN】高级时序规范(SPIN学习系列--6)

时序操作符[]&#xff08;总是&#xff09;和 <>&#xff08;最终&#xff09;可应用于任何LTL公式&#xff0c;因此 []<><>A 和 <>[]<>(A ∧ []B) 在语法上是正确的。本书不涉及LTL的演绎理论&#xff08;如公理、推理规则及公式的结合律、交换…...

C语言学习之内存函数

今天我们来学习一下C语言中内存函数 以下内存函数的使用均需要包含头文件<string.h> 目录 memcpy函数的使用及其模拟实现 memcpy函数的模拟实现 memmove函数的使用和模拟实现 memmove函数的模拟实现 memset函数的使用 memcmp函数的使用 memcpy函数的使用及其模拟实现…...

Python 数据库编程

一、数据库连接基础 1. 标准流程 import database_module # 如mysql.connector, sqlite3等 # 1. 建立连接 connection database_module.connect( host"localhost", user"username", password"password", database"dbnam…...

软考软件评测师——软件工程之开发模型与方法

目录 一、核心概念 二、主流模型详解 &#xff08;一&#xff09;经典瀑布模型 &#xff08;二&#xff09;螺旋演进模型 &#xff08;三&#xff09;增量交付模型 &#xff08;四&#xff09;原型验证模型 &#xff08;五&#xff09;敏捷开发实践 三、模型选择指南 四…...

机器学习入门

机器学习入门 1 . 机器学习是什么&#xff1f; 机器学习&#xff08;Machine Learning, ML&#xff09;是一种用数据经验替代显式规则编程来完成任务的方法──模型从样本 (X, y) 中学习 映射函数 f: X → Y&#xff0c;并在新样本上做出预测。和传统“if … else”程序相比&…...

git学习与使用(远程仓库、分支、工作流)

文章目录 前言简介git的工作流程git的安装配置git环境&#xff1a;git config --globalgit的基本使用新建目录初始化仓库&#xff08;repository&#xff09;添加到暂存区新增/修改/删除 文件状态会改变 提交到仓库查看提交&#xff08;commit&#xff09;的历史记录git其他命令…...

制造业或跨境电商相关行业三种模式:OEM、ODM、OBM

一、基础概念对比 模式定义核心能力利润来源控制权OEM代工生产&#xff08;贴牌生产&#xff09;纯生产制造能力加工费&#xff08;薄利&#xff09;品牌方掌控一切ODM设计生产&#xff08;自主设计代工&#xff09;设计研发能力设计溢价生产利润制造商掌握设计OBM自主品牌&am…...

APPtrace 智能参数系统:重构 App 用户增长与运营逻辑

一、免填时代&#xff1a;APPtrace 颠覆传统参数传递模式 传统 App 依赖「邀请码 / 手动绑定」实现用户关联&#xff0c;流程繁琐导致 20%-30% 的用户流失。APPtrace 通过 **「链接参数自动传递 安装后智能识别」** 技术&#xff0c;让用户在无感知状态下完成关系绑定、场景还…...

在 Excel 中使用 C# .NET 用户定义函数 操作步骤

点开选项 点击加载项 点击跳转 点击浏览 选择仙盟excel...

PyTest

一、基本用法: 1.测试框架做了什么: (1).测试发现 a.创建test_开头的文件 b.创建Test开头的类 c.创建test_开头的函数或方法 pytest中以每一个函数或方法作为一个用例 pytest主要以名字区分普通函数(方法)、用例 pytest的启动方式:在给定的项目中执行pytest命令即可 p…...

Python Day27 学习

今天学习讲义Day17的内容&#xff1a;无监督算法中的聚类浙大疏锦行 Q1. 什么是聚类&#xff1f; 本质上就是一种分组分类 关于聚类的准备工作&#xff1a; 代码实现 # 先运行之前预处理好的代码 import pandas as pd import pandas as pd #用于数据处理和分析&#xff…...

在 Win 10 上,Tcl/Tk 脚本2个示例

set PATH 新增 D:\Git\mingw64\bin where tclsh D:\Git\mingw64\bin\tclsh.exe where wish D:\Git\mingw64\bin\wish.exe 编写 test_tk.tcl 如下 #!/usr/bin/tclsh # test 文件对话框 package require Tk# 弹出文件选择对话框&#xff0c;限制选择.txt文件 set filePath […...

渐开线少齿差传动学习笔记

之前看到了一个渐开线一齿差的视频&#xff0c;觉得比较有意思&#xff0c;想自己动手做一个看看&#xff0c;下面是最开始尝试的一个失败的结果&#xff0c;不知道小伙伴们发现问题了没&#xff1f; 本来就是想凑一凑看看&#xff0c;但是发现不是凑起来不是件容易的事。那么…...