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

Django ORM 框架中的表关系,你真的弄懂了吗?

Django ORM 框架中的表关系

为了说清楚问题,我们设计一个 crm 系统,包含五张表:

1.tb_student 学生表

2.tb_student_detail 学生详情表

3.tb_salesman 课程顾问表

4.tb_course 课程表

5.tb_entry 报名表

表关系和字段如下图:

  如果你想学习自动化测试,我这边给你推荐一套视频,这个视频可以说是B站播放全网第一的自动化测试教程,同时在线人数到达1000人,并且还有笔记可以领取及各路大神技术交流:798478386   

【已更新】B站讲的最详细的Python接口自动化测试实战教程全集(实战最新版)_哔哩哔哩_bilibili【已更新】B站讲的最详细的Python接口自动化测试实战教程全集(实战最新版)共计200条视频,包括:1、接口自动化之为什么要做接口自动化、2、接口自动化之request全局观、3、接口自动化之接口实战等,UP主更多精彩视频,请关注UP账号。icon-default.png?t=N7T8https://www.bilibili.com/video/BV17p4y1B77x/?spm_id_from=333.337

接下来,根据这几个表我们来看在 django 中如何编写对应的模型,以及在数据库层面的处理。

多对一

在 django 中要表达多对一的关系需要使用 django.db.models.ForeignKeyField 字段。上图中,报名表和学生表,课程表,课程顾问表是多对一的关系,模型代码如下:


from django.db import modelsclass Student(models.Model): # 必须继承name = models.CharField('姓名', max_length=20, help_text='姓名')age = models.SmallIntegerField('年龄', null=True, blank=True, help_text='年龄')sex = models.SmallIntegerField('性别', default=1, help_text='性别')qq = models.CharField('qq号码', max_length=20, null=True, blank=True, unique=True, help_text='qq号码')phone = models.CharField('手机号码', max_length=20, null=True, blank=True, unique=True, help_text='手机号码')c_time = models.DateTimeField('创建时间', auto_now_add=True)def __str__(self):return self.nameclass Meta:db_table = 'tb_student'   # 设置创建表示的表名verbose_name = '学生信息'verbose_name_plural = verbose_name  # django admin中显示模型的说明class Salesman(models.Model):# GroupChoice = [#     ('电销', '电销'),#     ('网销', '网销'),#     ('班主任', '班主任'),# ]class GroupChoice(models.TextChoices):A = '电销', '电销'B = '网销', '网销'C = '班主任', '班主任'name = models.CharField('姓名', max_length=24, help_text='姓名')age = models.SmallIntegerField('年龄', null=True, blank=True, help_text='年龄')sex = models.SmallIntegerField('性别', default=1, help_text='性别')group = models.CharField('销售组', help_text='销售组', max_length=24, choices=GroupChoice.choices, default=GroupChoice.A )# group = models.CharField('销售组', help_text='销售组', max_length=24, choices=GroupChoice, default='电销')def __str__(self):return self.nameclass Meta:db_table = 'tb_salesman'verbose_name = '课程顾问表'verbose_name_plural = verbose_nameclass Course(models.Model):name = models.CharField('课程名称', max_length=24, help_text='课程名称', unique=True)price = models.IntegerField('价格', help_text='课程价格')period = models.SmallIntegerField('课时', help_text='课时,以小时为单位')def __str__(self):return self.nameclass Meta:db_table = 'tb_course'verbose_name = '课程表'verbose_name_plural = verbose_nameclass Entry(models.Model):student = models.ForeignKey(Student, verbose_name='学生', help_text='报名学生', on_delete=models.PROTECT)salesman = models.ForeignKey('Salesman', verbose_name='课程顾问', help_text='课程顾问', on_delete=models.PROTECT)course = models.ForeignKey(Course, verbose_name='课程', help_text='报名课程', on_delete=models.PROTECT, db_constraint=False)c_time = models.DateTimeField('报名时间', auto_now_add=True, help_text='报名时间')def __str__(self):return '{}-{}'.format(self.student.name, self.salesman.name)class Meta:db_table = 'tb_entry'verbose_name = '报名表'verbose_name_plural = verbose_name

定义 ForeignKeyField 字段时有如下注意事项

  1. 一般外键字段定义在多的一方

  2. 外键字段的第一个参数是一个位置参数,就是要关联的模型,可以是模型类本身,也可是字符串形式的导入路径(当引用其他应用的模型,和引入后定义的模型时很有用)

  3. 在数据库层面,django 会在字段名的后面附件 _id 来创建数据库列名。例如上面例子中的 Entry 模型的数据库表将有一个 student_id 列,然后为这个列创建一个外键约束,被引用的表为 tb_student,被引用的字段为 id.

    级联操作

    当一个由 ForeignKey 引用的对象被删除时,django 将模拟 on_delete 参数指定的 SQL 约束行为。

    注意是模拟,在数据库层面创建的外键的级联操作是 restrict。

  4. 注意:有时候为了效率,在数据库不会创建外键,而是通过代码逻辑来保证数据的完整性。在 django 中可以通过 ForeignKey 字段中指定 db_constraint=False 来控制不创建外键约束。所以上图中没有 course_id 的外键。

级联操作

当一个由 ForeignKey 引用的对象被删除时,django 将模拟 on_delete 参数指定的 SQL 约束行为。

注意是模拟,在数据库层面创建的外键的级联操作是 restrict。

 on_delete 的可能值有:

  • CASCADE

    • 级联删除

  • PROTECT

    • 通过引发 ProtectedErro 防止删除被引用字段

  • RESTRICT

    • 通过引发 RestrictErro 防止删除被引用字段

  • SET_NULL

    • 设置外键为空,只有当 null=true 才可以

ForeignKey 字段必须指定 on_delete。

一对一

在 django 中要表达一对一的关系需要使用 django.db.models.OneToOneField 字段,概念上类似于 ForeignKey 与 unique=True 的组合。

在 crm 中,学生详情表与学生表就是一个一对一的关系,创建模型如下:


class StudentDetail(models.Model):STATION_CHOICES = [('功能测试工程师', '功能测试工程师'),('自动化测试工程师', '自动化测试工程师'),('测试开发工程师', '测试开发工程师'),('测试组长', '测试组长'),('测试经理', '测试经理'),]class SalaryChoice(models.TextChoices):FIRST = '5000以下', '5000以下'SECOND = '5000-10000', '5000-10000'THIRD = '10000-15000', '10000-15000'FOURTH = '15000-20000', '15000-20000'FIFTH = '20000以上', '20000以上'student = models.OneToOneField(Student, verbose_name='学生', on_delete=models.CASCADE, help_text='学生')city = models.CharField('所在城市', max_length=24, help_text='所在城市', null=True, blank=True)company = models.CharField('任职公司', max_length=48, help_text='任职公司', null=True, blank=True)station = models.CharField('岗位', max_length=24, help_text='岗位', choices=STATION_CHOICES, default='功能测试工程师' )salary = models.CharField('薪资', max_length=24, help_text='薪资区间', choices=SalaryChoice.choices, default=SalaryChoice.FIRST)def __str__(self):return self.student.nameclass Meta:db_table = 'tb_student_detail'verbose_name = '学生详情表'verbose_name_plural = verbose_name

多对多

在 django 中要表达多对多的关系需要使用 django.db.models.ManyToManyField 字段,例如 Pizza 含有多种 Topping(配料),一种配料也可能存在于多个 pizza 中,每个 pizza 含有多种 topping 的关系,可以用下面的模型来表示:

class Topping(models.Model):name = models.CharField('名称', max_length=24)class Pizza(models.Model):name = models.CharField('名称', max_length=24)toppings = models.ManyToManyField(Topping)

 定义 ManyToManyField 字段时有如下注意事项

  1. 建议设置多对多字段名为一个复数名词,表示所要管理的模型对象的集合。

  2. 多以多对多关联的两个模型,可以在任何一个模型中添加多对多字段,但是只能选择一个模型设置,即不能在两个模型里都添加。

  3. 一般来讲,应该把多对多字段放到需要在表单中编辑的对象里。跟业务相关,具体情况具体对待。

  4. 在数据库层面,django 会自动创建一张中间表来表示多对多的关系。默认情况下,这个表名是使用多对多字段的名字和包含它的模型名生成(上面的例子,会生成 pizza_toppins),然后包含两个字段,分别是以两个关系模型的名字和 _id 组成(pizza_id,topping_id),并创建外键引用对应的表的 id。

图片

图片

自定义中间表

当表示多对多关系的中间表需要包含其他字段的时候,需要自定义中间表,然后再定义多对多字段的时候,通过 through 参数指定第三张表。

例如 crm 中的学生表和课程表的关系,通过报名表来表达,其中还包含了销售,创建时间字段。注意:创建学生,或者是创建课程的时候,都不需要去编辑彼此,这个时候建立多对多字段,主要是为了查询方便。然后通过课程查包名的学生表业务上可能用的更多,所以把多对多的字段定义在课程表中,代码如下:

class Course(models.Model):name = models.CharField('课程名称', max_length=24, help_text='课程名称', unique=True)price = models.IntegerField('价格', help_text='课程价格')period = models.SmallIntegerField('课时', help_text='课时,以小时为单位')students = models.ManyToManyField(Student, through='Entry', verbose_name='学生', help_text='包名课程的学生')def __str__(self):return self.nameclass Meta:db_table = 'tb_course'verbose_name = '课程表'verbose_name_plural = verbose_name

相关文章:

Django ORM 框架中的表关系,你真的弄懂了吗?

Django ORM 框架中的表关系 为了说清楚问题,我们设计一个 crm 系统,包含五张表: 1.tb_student 学生表 2.tb_student_detail 学生详情表 3.tb_salesman 课程顾问表 4.tb_course 课程表 5.tb_entry 报名表 表关系和字段如下图&#xff1a…...

第五课:C++实现加密PDF文档解密

请注意,未经授权的加密PDF文件解密是非法的,本文仅为学术和研究目的提供参考。 打开加密的PDF文件并获取密钥 在C++中,可以使用pdfium库打开加密的PDF文件。使用pdfium库中的FPDF_LoadCustomDocument函数可以打开具有自定义访问权限的加密文件。该函数接受一个IFX_FileRead*…...

罗马数字转整数

罗马数字转整数 题目: 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M …...

processflow流程图多人协作预热

前言 在线上办公如火如荼的今天,多人协作功能是每个应用绕不开的门槛。processflow在线流程图(前身基于drawio二次开发)沉寂两年之久,经过长时间设计开发,调整,最终完成了多人协作的核心模块设计。废话不多…...

PCL点云处理之快速计算多个点到同一直线的距离(二百零五)

PCL点云处理之快速计算多个点到同一直线的距离(二百零五) 一、算法简介二、具体实现1.代码2.结果一、算法简介 点到直线的距离计算,是一种常用的算法,在点云处理中,经常遇到需要计算多个点云到同一条直线的距离计算需求,此时若是逐点计算将耗费大量的时间,熟悉点到直线…...

xxl-job 任务调度搭建及简单使用

xxl-job是开源架构,可以通过它实现调度中心和执行器。 git地址和 官网中进行了详细的技术说明。   xxl-job支持单机部署和集群式部署,在集群式部署中又可以实现调度中心集群式部署和执行器集群式部署。本文主要针对调度中心和执行器分离单机部署方式进…...

mysql数据库使用技巧整理

查看当前数据库已建立的client连接 > SHOW VARIABLES LIKE max_connections; -- 查看数据库允许的最大连接数,不是实时正在使用的连接数 > SHOW STATUS LIKE Threads_connected; -- 查看当前数据库client的连接数 > SHOW PROCESSLIST; -- 查看具体的连接...

车规微控制器的ECC机制及EMU外设

车规微控制器的ECC机制及EMU外设 文章目录 车规微控制器的ECC机制及EMU外设引言ECC的基本原理ECC RAM的访问方式ECC RAM的初始化SRAM ECC错误注入及EMU外设Flash ECC校验参考文献 引言 ECC是微控制器系统中,用于保障信息安全的常用机制,主要是避免存储设…...

Less的强大变量用法

less中的变量应用十分强大,可以灵活的应用到各种不同需求的场景。 一,属性值变量 声明:sass声明变量是用$符号,而less声明变量是用符号 作用域:也区分为全局变量和局部变量,如果引用的变量有定义局部变量&…...

【相机标定】opencv python 标定相机内参时不计算 k3 畸变参数

文章目录 1. 背景2. 完整的 opencv python 标定相机内参过程3. 选择是否计算畸变参数 k3 1. 背景 畸变参数 k3 通常用于描述径向畸变的更高阶效应,即在需要高精度的应用中可以用到,一般的应用中 k1, k2 足矣。 常见的应用中, orbslam3 中是否…...

html 标签简介

概述 标签的效果不重要,重要的是标签的语义。 文本标签 文本标签用于包裹:词汇、短语等。排版标签,比如div,p,h1等。排版标签更宏观(大段的文字),文本标签更微观(词汇、短语)。文…...

dos汇编总结

前言: 计组课本需要学习汇编,可惜自己看不太懂。这里发现一个学习方法交给大家。其实新手可能一些抽象表示难理解,这里我把我学习的疑问点以及思路记录一下。 要点: 这里我以题为例给大家分析 输出输入对应大写字母的小写字母 …...

四川玖璨电子商务有限公司:短视频有什么运营

根据短视频有什么运营,短视频的拍摄工具多种多样。无论是在手机上拍摄还是使用专业摄影设备,拍摄短视频的目的都是为了吸引观众的注意力和提升内容的质量。从小花费到高投入,在不断发展的短视频行业中,拍摄方法也得到了不断创新和…...

混合查询多家快递,快速掌握物流信息

在现代社会,快递服务已成为我们日常生活的重要组成部分。无论是购物还是文件传递,我们都需要快递服务的帮助。然而,不同的快递公司需要不同的查询方法,这无疑增加了我们的查询难度。因此,有没有一种方法可以让我们一次…...

独立站新手引流,谷歌SEO工具汇总

俗话说“工欲善其事,必先利其器”,做谷歌SEO也一样,要想做好并提升SEO效果,卖家就需要了解并利用好SEO工具。那我们今天就来盘点一下,常用的SEO工具有哪些吧~ 网站检测工具 1、PageSpeed Insights:这是谷…...

SpringMvc 与 Lombok 碰撞导致 JSON 反序列化失败

SpringMvc 与 Lombok 中 JSON 反序列化失败 错误复现_1 Data public class User{private Long id;private boolean isOk; }RequestMapping public R<User> getUser(RequestBody User user){return R.success(user); }// 前端传参 - {"id": 123456789,"i…...

怎么样显卡叠加,什么是NVIDIA 显卡 非公、公版、涡轮卡

1、显存叠加的问题&#xff0c;因为这个跟是否是深度学习无关&#xff1a; 先说一下显存叠加的问题&#xff0c;因为这个跟是否是深度学习无关&#xff1a;一台机器有多张显卡&#xff0c;显存不会叠加&#xff01;显卡里面包含了显存、cache、计算单元、通信等&#xff0c;每…...

CentOS安装Elasticsearch集群

前言 之前使用的ES集群是其他公司维护&#xff0c;没有机会安装&#xff0c;后来做其他项目&#xff0c;终于有机会安装ES集群&#xff0c;简单记录一下备用 一、安装jdk 安装jdk1.8就可以&#xff0c;可以参考另一篇文章&#xff0c;这里就不细说了 二、修改系统参数 如果在…...

计算机专业毕业生指南

在大四毕业时&#xff0c;完成计算机毕业设计需要一定的计划和组织。以下是一些建议&#xff0c;帮助你在三个月内快速完成毕业设计&#xff1a; 选择一个合适的主题&#xff1a; 选择一个你感兴趣的主题&#xff0c;这将激发你的热情&#xff0c;使你更有动力完成项目。 确保…...

Springboot集成Docker并将镜像推送linux服务器

案例使用springboot项目&#xff0c;在IDEA 中集成Docker生成镜像&#xff0c;并将镜像发布到linux服务器 具体步骤如下&#xff1a; 1、Centos7安装Docker 更新系统的软件包列表 sudo yum update安装Docker所需的软件包和依赖项&#xff1a; sudo yum install docker完成…...

damaihelper:智能票务自动化系统 - 重新定义公平抢票技术范式

damaihelper&#xff1a;智能票务自动化系统 - 重新定义公平抢票技术范式 【免费下载链接】damaihelper 支持大麦网&#xff0c;淘票票、缤玩岛等多个平台&#xff0c;演唱会演出抢票脚本 项目地址: https://gitcode.com/gh_mirrors/dam/damaihelper 一、技术赋能&#…...

/etc/my.cnf的生命周期的庖丁解牛

/etc/my.cnf 的生命周期&#xff0c;常被误解为“数据库运行时实时读取的配置文件”。 但本质上&#xff0c;它是 MySQL 服务器进程 (mysqld) 启动时的“宪法”与“基因蓝图”。 它的生命周期严格绑定在 mysqld 进程的启动阶段。一旦进程启动完成&#xff0c;/etc/my.cnf 文件本…...

YimMenu:GTA V游戏增强与安全防护解决方案

YimMenu&#xff1a;GTA V游戏增强与安全防护解决方案 【免费下载链接】YimMenu YimMenu, a GTA V menu protecting against a wide ranges of the public crashes and improving the overall experience. 项目地址: https://gitcode.com/GitHub_Trending/yi/YimMenu 在…...

ThinkJS错误处理终极指南:构建稳定可靠的Node.js应用

ThinkJS错误处理终极指南&#xff1a;构建稳定可靠的Node.js应用 【免费下载链接】thinkjs Use full ES2015 features to develop Node.js applications, Support TypeScript. 项目地址: https://gitcode.com/gh_mirrors/thi/thinkjs ThinkJS是一个使用完整ES2015特性开…...

三步解决Windows系统驱动冗余难题:DriverStore Explorer系统优化指南

三步解决Windows系统驱动冗余难题&#xff1a;DriverStore Explorer系统优化指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 系统盘空间持续告急&#xff1f;设备管理器中出现重复驱…...

春联生成模型-中文-base环境隔离部署:Anaconda虚拟环境配置指南

春联生成模型-中文-base环境隔离部署&#xff1a;Anaconda虚拟环境配置指南 每次想尝试一个新的AI模型&#xff0c;最头疼的可能不是模型本身&#xff0c;而是环境配置。装了这个包&#xff0c;发现和之前项目的包版本冲突&#xff1b;好不容易跑起来&#xff0c;结果报了一堆…...

Cosmos-Reason1-7B生产环境:港口吊装作业视频力学合理性审计

Cosmos-Reason1-7B生产环境实战&#xff1a;港口吊装作业视频力学合理性审计 1. 项目背景与价值 港口吊装作业是物流运输的核心环节&#xff0c;但也是一个充满风险的场景。吊臂的每一次起降、货物的每一次摆动&#xff0c;背后都涉及复杂的力学原理。传统的安全审计主要依赖…...

OpenClaw代码助手:Qwen3-14b_int4_awq实现的自动补全与错误检查

OpenClaw代码助手&#xff1a;Qwen3-14b_int4_awq实现的自动补全与错误检查 1. 为什么需要本地化代码助手&#xff1f; 作为一名长期与代码打交道的开发者&#xff0c;我一直在寻找能够提升编程效率的工具。传统的IDE插件虽然能提供基础补全&#xff0c;但存在几个痛点&#…...

Intv_ai_mk11集成Node.js环境配置:快速构建实时聊天应用

Intv_ai_mk11集成Node.js环境配置&#xff1a;快速构建实时聊天应用 1. 环境准备与快速部署 在开始构建实时聊天应用之前&#xff0c;我们需要确保开发环境已经准备就绪。这里假设你已经具备基本的JavaScript和Node.js知识。 首先&#xff0c;确保你的系统已经安装了Node.js…...

Qwen3-ForcedAligner-0.6B完整指南:音频格式支持/实时录音/时间戳导出全解析

Qwen3-ForcedAligner-0.6B完整指南&#xff1a;音频格式支持/实时录音/时间戳导出全解析 你是不是也遇到过这样的烦恼&#xff1f;开会录音想整理成文字&#xff0c;手动打字累到怀疑人生&#xff1b;做视频需要加字幕&#xff0c;一句一句对时间轴对到眼花。今天要介绍的这个…...