我们先对单表查询做一个总结和回顾,并进行进一步的学习和交流。我们在我们的应用的models.py文件下面书写user类。如下所示,然后用数据库迁移,在mysql数据库中生成表。然后进行数据库表的单表查询的操作。
我们之前学了单表操作的知识,在这里我们巩固一下,并且进行更深入一步的学习。我们之前测试我们的models文件是否正常,数据库迁移是否正确,我们都是采用的是前后端交互的技术实现测试的。但是我们知道django的orm语句是比较多的,我们每次对于数据库的操作,orm语句的操作都需要前后端来测试的话,那么这个是十分的麻烦。在这里我们在学习单表操作的同时,也引进了关于测试环境准备的知识点,那么以后我们写好的.py文件的代码,我们可以放到我们的测试环境中,即test.py文件中进行测试。脚本代码无论是写在自己应用下的test.py中,还是自己单独开设.py文件都可以。
测试环境的准备:去manager.py中copy这个文件的前面四行代码,然后自己写两行。测试文件是通用的一个功能,不一定是在应用下的test.py文件,自己也可以新建测试的.py文件,例如mytest.py文件。
在这个代码块下面就可以测试django里面的单个py文件了。所有的代码都要写在测试环境的下面,因为测试环境还没有准备好,我们必须放在测试环境的下面,等待测试环境准备好之后,我们才可以开始测试。所有的代码必须等待环境准备好之后才可以开始书写。
现在我们在我们的测试环境下来测试、使用、学习和扩展我们的单表查询。
1)all():查询所有
2)filter():带有过滤条件的查询
3)get():直接拿数据对象,但是条件不存在那么会直接报错,不推荐使用。
4)first():拿到queryset里面的第一个元素,即第一个数据对象(queryset是列表套数据对象)
5)last():拿到queryset里面的最后一个元素,即最后一个数据对象(queryset是列表套数据对象)
6)values():可以指定的获取的数据字段 select name,age from ..... 类似于列表套字典
7)values_list():可以指定的获取的数据字段 select name,age from ..... 类似于列表套元组
8)distinct():去重
9)order_by():排序
10)reverse():反转,先排序,才可以反转,是建立在排序的基础上的
11)count():统计数量
12)exclude():除了什么之外,排除在外。
13)exists():判断是否存在,返回的是布尔值,基本用不到因为数据本身就自带布尔值。
1.我们要你帮我查出年龄大于35岁的数据
2.我们要你帮我查出年龄小于35岁的数据
3.我们要你帮我查出年龄大于等于35岁的数据
4.我们要你帮我查出年龄小于等于35岁的数据
5.我们要你帮我查出年龄是18或者35或者38
6.我们要你帮我查出年龄在18到48岁之间的,首位都要
7.我们要你帮我查出名字里面含有n的数据,模糊查询,区分大小写
8.我们要你帮我查出名字里面含有n的数据,模糊查询,忽略大小写
9.我们要你帮我查出名字以Z为开头
10.我们要你帮我查出名字以U为结尾
11.我们要你帮我查出注册时间的月
12.我们要你帮我查出注册时间的年
我们在做多表查询的之前需要做一些准备工作,下面就是我们准备工作要写的模型类,将写好的模型类迁移到数据库中,这样我们就可以开始做我们的多表的查询。模型类的代码如下所示。
我们前面已经建立了表之间的关系,那么我们现在可以使用orm框架实现外键的增删改查,因为查是最难的知识点,所以我们将查和增删改分开讲解,我们先讲解增删改,后面再讲解查。
1)一对一、一对多外键的增删改
2)多对多外键增删改清空
接下来我们学习多对多外键的增删改,我们依次用下面的代码来写:
在我们讲解多表查询的时候,我们在这里先学一个概念,这个概念就是关于正反向的概念,如果我们弄清楚了这个概念以后,我们的下面的学下就会表的更加的轻松。
外键字段在我手上,那么我查你就是正向。外键字段如果不在我手上,那么我查你就是反向。
book 》》》外键字段在书哪儿(正向)》》》publish
publish》》》外键字段在书哪儿(反向)》》》book
一对一,多对多正反向的判断也是如此
正向查询按字段,如果我们发现结果是有多个的时候我们是字段加上all(),如果发现结果只有一个的时候,我们是字段即可。
反向查询按表名小写,如果发现结果有多个的时候我们是表名小写加,并且还要加上all()。如果是单个的时候我们是直接表名小写,也不用加
1)正向查询
1.查询书籍主键为1的出版社名称
2.查询书籍主键为2的作者
3.查询作者jason的电话号码
上面我们得到了一个特点是:利用orm跨表查询是比较的简单。在书写orm语句的时候跟写sql语句是一样的,不要企图一次性将orm语句写完,如果比较复杂,就写一点看一点,分段写
正向的时候什么时候需要加.all()呢?当你的结果可能有多个的时候就需要加.all(),如果是一个则直接拿到数据对象。
2)反向查询
4.查询出版社是北京出版社出版的书籍
5.查询作者是jason写过的书
6.查询手机号是110的作者姓名
基于对象反向查询的时候的规律
当你的查询结果可以有多个的时候,我们就必须表名小写加上_set.all()
当你的查询结果只有一个的时候,我们就必须是表名小写,不需要加_set.all()
例子1.查询书籍主键为1的出版社名称(一行代码搞定)
select Publish.name from (select * from Book,Publish where publish_id = Publish.id ) as Book_Publish where Book.id =1;
1.查询jason的手机号和作者姓名
2.查询书籍主键为1的出版社名称和书的名字
3.查询书籍主键为1的作者姓名
4.查询书籍主键是1的作者的手机号
Book Author AuthorDetail
你只要掌握了正反向的概念以及双下划线的查询,那么你就可以无限制的跨表查询,联表查询。
在这里我们先学习一个东西,我们必须明白一个理论的知识。这个理论知识就是:只要是跟数据库相关的模块基本上都在django.db.models里面,如果上述没有那么应该在django.db里面。聚合函数涉及的一般是如下:max,min,sum,count,avg,在django中,我们应该使用aggregate()。
分组在mysql中是group by,在我们的django是用annotate作为分组的使用。一般分组和聚合是在一起使用的。两者相辅相成,也就是我们平时所说的分组聚合。
MySQL分组查询有哪些特点呢?分组时候默认只能获取到分组的依据,组内其他字段无法直接获取了。因为MySQL默认是严格模式,ONLY_FULL_GROUP_BY
我们看下面的几个题目来深刻的体会和理解分组查询的意义和内涵。
在这里我们补充一个知识点,这个知识点就是:只要你的orm语句得出来的结果还是一个QuerySet对象,那么它就可以继续无限制的点QuerySet对象封装的方法。
还有一个知识点就是,如果我想要按照指定的字段分组该如何处理呢?
models.Book.objects.values('price').annotate(),后续我们在写项目的时候会使用到这个知识点。
我们现在来讲解一下什么是F查询,F查询的用途是什么呢?
F查询:能够帮助你直接获取到列表中某个字段对应的数据
1.查询卖出数大于库存数的书籍
2.将所有书籍的价格提升50块
3.将所有书的名称后面加上爆款两个字(了解)
在学习Q查询之前,我们先来说明一个问题,filter默认只是支持使用的是与(and)关系。但是往往这样一种关系是不能满足于我们平时的使用。所以我们需要更多的逻辑关系,使得我们更加的操作方便,因此我们在这里引入了一种查询方式,这个查询方式叫做Q查询。
1.查询卖出数大于100或者价格小于600的书籍
2.Q的高阶用法 能够将查询条件左边也变成字符串的形式,而不再是变量名的形式。使用Q我们可以实现一个简单的搜索功能。
事务:我们知道事务有四个特性,这四个特性分别是:
原子性:不可分割的最小单位。
一致性:跟原子性是相辅相成的。
隔离性:事务之间是互相不干扰。
持久性:事务一旦确认是永久有效的。
事务的回滚:rollback
事务的确认:commit
参考:https://www.cnblogs.com/liuqingzheng/articles/9627915.html