文章目录

  • 前言
  • 1.一对一
    • 级联插入
      • 方法1.save()
      • 方法2.objects.create
    • 级联查询
      • 正向查询
      • 逆向查询
  • 2.一对多
      • 班级主表(一)
      • 学生从表(多)
    • 级联插入
    • 正向查询
    • 逆向查询
      • 关联名可以修改
    • 制作函数:批量插入两表
  • 3.多对多
    • 插入
    • 查询
    • 制作函数,批量插入三个表
      • 可变参数
      • 参数解包

前言

上一章只学了单表,对于论坛等网站,会有很多表之间关联,用sql语言需要嵌套,相当繁琐,下面我们看下如何用django自带的代码来处理这些表格。

  1. 一对一:学生和学生证
    一个学生只有一个证,一个证只属于一个学生
student = `models.OneToOneField(Student,primary_key=True,on_delete=models.CASCADE)`
  1. 一对多:班级和学生
    一个班级多个学生,一个学生一个班级
clazz = models.ForeignKey(Clazz,related_name='student')
  1. 多对多:学生和课程
course = models.ManyToManyField(Course)

1.一对一

在model里建两个class
student1,包括sno和sname
scard,包括student和major

其中student与sno通过onetoonefield级联,并可同步删除CASCADE

class Student1(models.Model):sno = models.AutoField(primary_key=True)sname = models.CharField(max_length=30)def __str__(self):return 'Student1:%s' % (self.sname)class Scard(models.Model):# ondelete默认也是级联student = models.OneToOneField(Student1, primary_key=True, on_delete=models.CASCADE)major = models.CharField(max_length=30, unique=True)def __str__(self):return 'Scard:%s' % (self.major)

级联插入

方法1.save()

注意第二个表需要引入第一个表的插入变量stu

stu = Student1(sname='zhangsan')
stu.save()
#用第一个表的stu
sc = Scard(student=stu,major='计算机')
sc.save()

tip:在pycharm里可以修改model,不用保存,但console不会实时更新,如果不重启会找不到新的model

方法2.objects.create

第一个表的插入过程还是需要放在变量stu1,给第二个表格级联

stu1 = Student1.objects.create(sname='lisi')
Scard.objects.create(student=stu1,major='数学')
<Scard: Scard:数学>

级联查询

Student1先创建,然后Scard里加了级联
所以正向查询是按A条件查到B的信息

正向查询

Student1.objects.first().scard
<Scard: Scard:计算机>

最后的scard取的是B的小写名字,输出B的默认格式

逆向查询

按B的级联项,查A的信息

Scard.objects.first().student
<Student1: Student1:zhangsan>

最后的student取的是B级联的名字

2.一对多

班级主表(一)

class Clazz(models.Model):cno = models.AutoField(primary_key=True)cname = models.CharField(max_length=30)

学生从表(多)

class Student2(models.Model):sno = models.AutoField(primary_key=True)sname = models.CharField(max_length=30)cno = models.ForeignKey(Clazz,on_delete=models.CASCADE)def __str__(self):return 'Student2:%s' % self.sname

可以看到一对多,在第二个表里用foreignkey来关联
在右侧可以看到表结构,级联删除不能空着,但是写了也没用,需要手动设置
视频里不知道是不是版本问题,不需要用它那个软件,pycharm完全可以做得到

级联插入

这里直接用objects.create的方法,不用save了
批量操作:
第一个表查插入两个过程,cls和cls1,
在第二个表插入的时候选择引用

from stu.models import *
cls=Clazz.objects.create(cname='B201Python')
cls1=Clazz.objects.create(cname='B202Java')
Student2.objects.create(sname='zhangsan',cno=cls)
Student2.objects.create(sname='lisi',cno=cls)
Student2.objects.create(sname='wangwu',cno=cls1)

正向查询

还是取B的表名
一对多,Clazz是一,student2是多,自动提示变成了student2_set

Clazz.objects.first().student2_set.all()
<QuerySet [<Student2: Student2:zhangsan>, <Student2: Student2:lisi>]>

逆向查询

Student2.objects.first().cno

cno还是取的B的级联项名。

关联名可以修改

在Student2的ForeigKey后面加related_name=‘sts’
正向查询变成

Clazz.objects.first().sts.all()

制作函数:批量插入两表

需求:插入一个新班级名称cname,两个学生名称sname
函数可以定义*可变参数
先判断是否存在:
如果存在,用cls获取信息以备第二个表用
查询方式get,不存在时会报异常,异常有DoesNotExist的固定格式,插入一条数据,保存为cls,以备第二个表级联用

第二个表还是先判断是否存在,存在则不插入;
不存在则插入,用刚才的变量cls


def insertData(clsname,*snames):try:cls = Clazz.objects.get(cname=clsname)except Clazz.DoesNotExist:cls = Clazz.objects.create(cname=clsname)for sn in snames:try:stu = Student2.objects.get(sname=sn)except Student2.DoesNotExist:Student2.objects.create(sname=sn,cno=cls)
insertData('B203HTML5班','zhangjie','xiena')

用到了知识点,可变参数,即对参数进行了打包,*代表元祖,**是字典。

3.多对多

课程和老师两个表格,一个课程可以多个老师教,一个老师可以教多个课程,所以是多对多关系

设置ManyToManyField,会自动创建中间表,teacher_cour,有两个外键分别对应两个表,可以手动设置为cascade级联删除和修改

class Course(models.Model):course_no = models.AutoField(primary_key=True)course_name = models.CharField(max_length=30)def __str__(self):return 'Course:%s' % self.course_nameclass Teacher(models.Model):tno = models.AutoField(primary_key=True)tname = models.CharField(max_length=30)cour = models.ManyToManyField(Course)def __str__(self):return 'Teacher:%s' % self.tname

插入

其实创建的课程和老师表里,并没有老师教什么课的信息,而是在中间表teacher_cour里,所以这两个表可以单独插入新的条目,过程为a(cour1-3)和b(t和t2)
通过过程b点级联字段点add(过程a),可以将刚才插入的语句建立关系到中间表里

from stu.models import *
cour1 = Course.objects.create(course_name='Python')
cour2 = Course.objects.create(course_name='Java')
cour3 = Course.objects.create(course_name='HTML5')
t = Teacher.objects.create(tname='zhangsan')
t2 = Teacher.objects.create(tname='lisi')
t.cour.add(cour1,cour2,cour3)

查询

跟一对多类似,正向查小写b的_set,逆向查级联名,
两边都是多,所以都是.all()

Course.objects.first().teacher_set.all()
Teacher.objects.first().cour.all()

制作函数,批量插入三个表

一个老师,三个课程

def insertData(tname,*coursenames):try:t = Teacher.objects.get(tname=tname)except Teacher.DoesNotExist:t = Teacher.objects.create(tname=tname)courseList = []for cn in coursenames:try:cou = Course.objects.get(course_name=cn)except Course.DoesNotExist:cou = Course.objects.create(course_name=cn)courseList.append(cou)#数组的解包t.cour.add(*courseList)insertData('wangwu','Oracle','MySQL')

可变参数

*代表元祖
**代表字典,是键值对

def demo(*args, **kwargs):print args,kwargs
demo(1,2,c='a',b='d')
(1, 2) {'c': 'a', 'b': 'd'}

函数定义的参数是元祖或字典,若传给它单独的元素,会打包变成元祖或字典

参数解包

若函数定义是单独的元素,传递给它元祖和字典,会解包拆成单独的元素

def demo(a,b,c):print(a,b,c)
str = {'a':'a1','b':'b1','c':'c1'}
demo(**str)
a1 b1 c1

刚才在函数定义时,用到了可变参数,可根据传递的单个数值打包成元祖,以便循环遍历;注意固定参数在前面,可变参数在后面
在添加add时,用到了数组解包,因为add语法要求括号后面是多个单元素,先建空数组,多个课程放在add后面

ps.这个老师讲的还可以,就是python和django比较旧,而且每节课之间太重复了,每节课都要重新建一遍app…

Django Model 2.数据库—多表查询相关推荐

  1. python Django 连接mysql数据库创建表详细全过程

    python Django 连接mysql数据库创建表详细全过程 1,在数据库中新建一个要连接的数据库(在cmd命令行里登录数据库进行创建创建) mysql -u root -p**+密码** cre ...

  2. 面向考试数据库—单表查询(包含建表数据)

    面向考试数据库-单表查询(包含建表数据) 引言 ● 建立练习数据库(之后习题亦是基于该库) 建表源码 单表查询知识点汇总 单表查询练习题32道 (1)选取表中的若干列 (2)选择表中若干元祖 (3)o ...

  3. access查询mysql_2017计算机二级Access数据库生成表查询教程

    2017计算机二级Access数据库生成表查询教程 引导语;你知道运用Access数据库如何查询生成表吗,以下是百分网小编分享给大家的2017计算机二级Access数据库生成表查询教程,欢迎阅读! 生 ...

  4. mysql数据库多表查询(内连接,外连接,自连接,子查询及案例分析)

    mysql数据库多表查询 之前接触的项目或者自己涉及的部分对于多表查询的使用都比较的少,常常是自己更具案例进行学习,最近见到的比较的多,所以今天就好好的总结一下,为下一步学习做准备! 1.多表查询关系 ...

  5. 数据库系统概论 实验报告答案 实验五:数据库单表查询

    实验五:数据库单表查询 一.实验目的 1. 掌握SELECT语句的基本语法和查询条件表示方法: 2. 掌握查询条件表达式和使用方法: 3. 掌握GROUP BY 子句的作用和使用方法: 4. 掌握HA ...

  6. MySQL数据库多表查询

    MySQL数据库多表查询 前言 在之前的文章MySQL数据库之SQL入门中,我们讲到了四类SQL中的DQL(数据库查询语言,用于查询表中数据),但是我仅仅用DQL去查询一张表中数据,而在实际的应用中, ...

  7. Oracle数据库—— 多表查询

    Oracle数据库-- 多表查询 (一)笛卡尔问题 1.笛卡尔积会在下面条件下产生: 省略连接条件 连接条件无效 所有表中的所有行互相连接 2.为了避免笛卡尔积,可以在WHERE加入有效的连接条件 ( ...

  8. 数据库单表查询 - 简单筛选查询

    写在前面:博主是一只经过实战开发历练后投身培训事业的"小山猪",昵称取自动画片<狮子王>中的"彭彭",总是以乐观.积极的心态对待周边的事物.本人的技 ...

  9. 064.django之模型层单表查询

    文章目录 一.orm简介 (一) orm概述 (二) django中orm的使用 二.单表操作 (一) 创建表 1 创建模型 2 常用的字段.参数和元信息 3 settings配置信息 4 增加.删除 ...

最新文章

  1. 基于GANs的图像编辑方法
  2. 将特定像素点在图像上连接起来_图像分割【论文解读】快速图像分割的SuperBPD方法 CVPR-2020...
  3. linux去重文件第一列,科学网—Linux实用命令 - 刘洪波的博文
  4. 过分了,这样阅读Datasheet(数据手册)合适吗?
  5. php获取页面的可视内容高度,网页制作技巧:获取页面可视区域的高度_css
  6. LeetCode 703. 数据流中的第K大元素(优先队列)
  7. 风机桨叶故障诊断(七) 滑动窗与非极大值抑制NMS
  8. 修改list中对象的值_怎样在S7-200 SMART中监控和修改变量的值?
  9. Python使用matplotlib进行可视化时精确控制图例位置
  10. matlab2c使用c++实现matlab函数系列教程-wilkinson函数
  11. ajax post请求怎么传参_如何在$ ajax POST中传递参数?
  12. 用matlab代码分析不同尺寸的卷积核对图像的影响
  13. nginx 工作原理
  14. python随笔12(传递任意数量的实参)
  15. IOI2021集训队作业
  16. python dataframe 列筛选_pandas系列之DataFrame 行列数据筛选实例
  17. JavaScript中deferred对象浅析
  18. 新式 AIMD 拥塞控制
  19. img src 无法显示图片问题
  20. 交叉编译器 arm-linux-gnueabi,arm-linux-gnueabihf,arm-none-linux等的区别

热门文章

  1. 百度地图 ( 二 ) 添加覆盖物
  2. PCB标记的埋雷设计,短路了却找不到一丝踪迹
  3. 【跨保985计算机】2022跨保实录|六千字保姆教程
  4. R-forestplot包| HR结果绘制森林图
  5. 【组成原理-总线】总线的概念和计算
  6. layui写弹出框显示表单信息_layui 弹出框提交表单
  7. 刘艺新作:Thinking in Patten with Delphi
  8. python中图片转PDF的2种方法
  9. 计量经济学及Stata应用 第三章习题
  10. 使用anaconda创建一个虚拟环境