当前位置: 首页 > 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完成…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...