优化手机访问网站速度,哈尔滨网站搜索优化公司,温州联科网站建设,公司网站模块制作Django ORM 框架中的表关系 为了说清楚问题#xff0c;我们设计一个 crm 系统#xff0c;包含五张表#xff1a;
1.tb_student 学生表
2.tb_student_detail 学生详情表
3.tb_salesman 课程顾问表
4.tb_course 课程表
5.tb_entry 报名表
表关系和字段如下图#xff1a…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账号。https://www.bilibili.com/video/BV17p4y1B77x/?spm_id_from333.337
接下来根据这几个表我们来看在 django 中如何编写对应的模型以及在数据库层面的处理。
多对一
在 django 中要表达多对一的关系需要使用 django.db.models.ForeignKeyField 字段。上图中报名表和学生表课程表课程顾问表是多对一的关系模型代码如下 from django.db import modelsclass Student(models.Model): # 必须继承name models.CharField(姓名, max_length20, help_text姓名)age models.SmallIntegerField(年龄, nullTrue, blankTrue, help_text年龄)sex models.SmallIntegerField(性别, default1, help_text性别)qq models.CharField(qq号码, max_length20, nullTrue, blankTrue, uniqueTrue, help_textqq号码)phone models.CharField(手机号码, max_length20, nullTrue, blankTrue, uniqueTrue, help_text手机号码)c_time models.DateTimeField(创建时间, auto_now_addTrue)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_length24, help_text姓名)age models.SmallIntegerField(年龄, nullTrue, blankTrue, help_text年龄)sex models.SmallIntegerField(性别, default1, help_text性别)group models.CharField(销售组, help_text销售组, max_length24, choicesGroupChoice.choices, defaultGroupChoice.A )# group models.CharField(销售组, help_text销售组, max_length24, choicesGroupChoice, default电销)def __str__(self):return self.nameclass Meta:db_table tb_salesmanverbose_name 课程顾问表verbose_name_plural verbose_nameclass Course(models.Model):name models.CharField(课程名称, max_length24, help_text课程名称, uniqueTrue)price models.IntegerField(价格, help_text课程价格)period models.SmallIntegerField(课时, help_text课时,以小时为单位)def __str__(self):return self.nameclass Meta:db_table tb_courseverbose_name 课程表verbose_name_plural verbose_nameclass Entry(models.Model):student models.ForeignKey(Student, verbose_name学生, help_text报名学生, on_deletemodels.PROTECT)salesman models.ForeignKey(Salesman, verbose_name课程顾问, help_text课程顾问, on_deletemodels.PROTECT)course models.ForeignKey(Course, verbose_name课程, help_text报名课程, on_deletemodels.PROTECT, db_constraintFalse)c_time models.DateTimeField(报名时间, auto_now_addTrue, help_text报名时间)def __str__(self):return {}-{}.format(self.student.name, self.salesman.name)class Meta:db_table tb_entryverbose_name 报名表verbose_name_plural verbose_name
定义 ForeignKeyField 字段时有如下注意事项 一般外键字段定义在多的一方 外键字段的第一个参数是一个位置参数就是要关联的模型可以是模型类本身也可是字符串形式的导入路径(当引用其他应用的模型和引入后定义的模型时很有用) 在数据库层面django 会在字段名的后面附件 _id 来创建数据库列名。例如上面例子中的 Entry 模型的数据库表将有一个 student_id 列然后为这个列创建一个外键约束被引用的表为 tb_student被引用的字段为 id. 级联操作 当一个由 ForeignKey 引用的对象被删除时django 将模拟 on_delete 参数指定的 SQL 约束行为。 注意是模拟在数据库层面创建的外键的级联操作是 restrict。 注意有时候为了效率在数据库不会创建外键而是通过代码逻辑来保证数据的完整性。在 django 中可以通过 ForeignKey 字段中指定 db_constraintFalse 来控制不创建外键约束。所以上图中没有 course_id 的外键。
级联操作
当一个由 ForeignKey 引用的对象被删除时django 将模拟 on_delete 参数指定的 SQL 约束行为。
注意是模拟在数据库层面创建的外键的级联操作是 restrict。 on_delete 的可能值有 CASCADE 级联删除 PROTECT 通过引发 ProtectedErro 防止删除被引用字段 RESTRICT 通过引发 RestrictErro 防止删除被引用字段 SET_NULL 设置外键为空只有当 nulltrue 才可以
ForeignKey 字段必须指定 on_delete。 一对一 在 django 中要表达一对一的关系需要使用 django.db.models.OneToOneField 字段概念上类似于 ForeignKey 与 uniqueTrue 的组合。
在 crm 中学生详情表与学生表就是一个一对一的关系创建模型如下 class StudentDetail(models.Model):STATION_CHOICES [(功能测试工程师, 功能测试工程师),(自动化测试工程师, 自动化测试工程师),(测试开发工程师, 测试开发工程师),(测试组长, 测试组长),(测试经理, 测试经理),]class SalaryChoice(models.TextChoices):FIRST 5000以下, 5000以下SECOND 5000-10000, 5000-10000THIRD 10000-15000, 10000-15000FOURTH 15000-20000, 15000-20000FIFTH 20000以上, 20000以上student models.OneToOneField(Student, verbose_name学生, on_deletemodels.CASCADE, help_text学生)city models.CharField(所在城市, max_length24, help_text所在城市, nullTrue, blankTrue)company models.CharField(任职公司, max_length48, help_text任职公司, nullTrue, blankTrue)station models.CharField(岗位, max_length24, help_text岗位, choicesSTATION_CHOICES, default功能测试工程师 )salary models.CharField(薪资, max_length24, help_text薪资区间, choicesSalaryChoice.choices, defaultSalaryChoice.FIRST)def __str__(self):return self.student.nameclass Meta:db_table tb_student_detailverbose_name 学生详情表verbose_name_plural verbose_name 多对多
在 django 中要表达多对多的关系需要使用 django.db.models.ManyToManyField 字段例如 Pizza 含有多种 Topping(配料)一种配料也可能存在于多个 pizza 中每个 pizza 含有多种 topping 的关系可以用下面的模型来表示
class Topping(models.Model):name models.CharField(名称, max_length24)class Pizza(models.Model):name models.CharField(名称, max_length24)toppings models.ManyToManyField(Topping) 定义 ManyToManyField 字段时有如下注意事项 建议设置多对多字段名为一个复数名词表示所要管理的模型对象的集合。 多以多对多关联的两个模型可以在任何一个模型中添加多对多字段但是只能选择一个模型设置即不能在两个模型里都添加。 一般来讲应该把多对多字段放到需要在表单中编辑的对象里。跟业务相关具体情况具体对待。 在数据库层面django 会自动创建一张中间表来表示多对多的关系。默认情况下这个表名是使用多对多字段的名字和包含它的模型名生成上面的例子会生成 pizza_toppins)然后包含两个字段分别是以两个关系模型的名字和 _id 组成(pizza_id,topping_id)并创建外键引用对应的表的 id。 自定义中间表
当表示多对多关系的中间表需要包含其他字段的时候需要自定义中间表然后再定义多对多字段的时候通过 through 参数指定第三张表。
例如 crm 中的学生表和课程表的关系通过报名表来表达其中还包含了销售创建时间字段。注意创建学生或者是创建课程的时候都不需要去编辑彼此这个时候建立多对多字段主要是为了查询方便。然后通过课程查包名的学生表业务上可能用的更多所以把多对多的字段定义在课程表中代码如下
class Course(models.Model):name models.CharField(课程名称, max_length24, help_text课程名称, uniqueTrue)price models.IntegerField(价格, help_text课程价格)period models.SmallIntegerField(课时, help_text课时,以小时为单位)students models.ManyToManyField(Student, throughEntry, verbose_name学生, help_text包名课程的学生)def __str__(self):return self.nameclass Meta:db_table tb_courseverbose_name 课程表verbose_name_plural verbose_name