1.前言

django的ORM框架提供的查询数据库表数据的方法很多,不同的方法返回的结果也不太一样,不同方法都有各自对应的使用场景。

主要常用的查询方法个数是13个,按照特点分为这4类:

  • 方法返回值是可迭代对象QuerySet:all(),filter(),exclude(),order_by(),reverse(),values(),values_list(),distinct();
  • 方法返回值是单个对象:get(),first(),last();
  • 方法返回值是布尔值:exists();
  • 方法返回值是数字:count();

细节:

①.学习任何一个web开发框架比如django,框架都会提供满足90%的开发人员使用的封装的很健壮的很多方法,每个方法都能实现相应的功能,这样开发人员不用花大量时间去写这些类似的方法也就避免了重复造轮子而且开发人员自己造的轮子一般健壮性不高适用场景不多。所以对于使用框架的我们而言,知道框架提供了哪些方法并知道每个方法具体怎么用的例子,我们就能很轻松地进行业务开发!

2.数据准备

为了结合实际例子,来验证这13个查询方法怎么使用,需要提前在指定的数据表里造好数据。

所以,我选择用【hello_person】表的这三条数据当做测试数据。

3.方法返回值是可迭代对象QuerySet的每个查询方法的如何使用的完整记录

细节:

①.通过之前的接口调试,我们知道视图函数【search_person】已经能被正常调用并返回我们预期的结果值。所以我们每次验证一个查询方法,就可以通过改造这个视图函数【search_person】里的相关代码逻辑来进行验证。

3.1.查询方法【all()】如何使用的完整记录

细节:

①.首先,我们知道查询一张数据表【hello_person】的所有数据的原生sql语句是:select * from hello_peroson。

②.但是,我们通过ORM框架提供的任何一个方法就都不需要写原生sql语句,比如执行这行代码【allData = 一张数据表对应的类名称.objects.all()】就能返回这张表的所有数据即所有数据都存储在这个变量【allData】里,变量【allData】是可迭代对象QuerySet,即我们要记住变量【allData】在此时是一个可迭代对象,并没有直接给我们返回全部数据而是间接返回全部数据。如果要取出可迭代对象【allData】里的具体的数据表数据,必须要用for循环进行读取,因为for循环就是专门用来处理列表和字典和元祖和可迭代对象的这些可被迭代的数据类型!

③.可迭代对象QuerySet的初步理解:可以把python语言里的可迭代对象QuerySet看成是java语言里的结果集,结果集可以看成是列表,结果集的作用是用于存储每个不同的对象/不同的元祖/不同的字典。而我们也知道每个对象都是唯一的因为每个对象内存地址都是唯一的,每个类被实例化一次后就会生成对应的一个对象,我们可以通过对象去调用类里面的相关类属性相关方法去获取我们想要的具体的数据表表数据。

④.通过ORM框架提供的【all() 】方法的返回值是一个可迭代对象QuerySet类型数据,该类型数据类似于list。这个可迭代对象QuerySet类型数据里面每个数据都是模型类的对象。

⑤.

问题:

结果集为什么基本用来存储从数据表获取的数据?

大概答案:

假如一张数据表有10万条数据,结果集里肯定有10万个不同的对象,通过每个对象可以方便后期获取对应的这条数据表数据的相关表字段数据。

django会对【all()】方法返回的这个可迭代对象QuerySet类型数据进行缓存,这是为了提高查询效率。也就是说,在我们创建一个迭代对象QuerySet的时候,django并不会立即向数据库发出查询命令而只是获取到对应数据里每条表数据对应的每个不同的模型类对象,只有在我们需要用到这个迭代对象QuerySet(通过for循环去调用模型类的对象)的时候才会触发调用模型类对象里的相关方法或者相关类属性去执行相关sql语句的查询命令。

⑥.

问题:如何用比较接地气的文案来描述用于存储对象的结果集的作用?

大概答案:

比如一张数据表A里有10条数据,把一张数据表A的每条数据看成一个结果,我们就需要用每个不同的对象去装载每个不同的结果。

就比如:一辆车装一个人,一个对象装一个结果。

然后现在有10个不同的人,就必须需要10辆不同的车。

可以把结果集理解为是一个很大的装车的集装箱,可以通过这个集装箱装这10辆车。

最终,我们拿到了这个集装箱,可以通过【for循环】这个开集装箱工具去获取到所有的车所有的人和每个人不同的具体数据。

⑦.

问题:

比如我一张数据表A里有1万条表数据,现在我想要获取到这张数据表A所有表字段的具体值,有以下这两个方案:
方案1:自己直接写一条原生aql语句,直接返回这1万条数据的所有表字段值的具体值。    
方案2:通过orm框架提供的一个方法all()返回有包含1万条数据对应的对象的结果集,接着通过对象去调取相关类属性或者方法去获取到表字段值的具体值。
请问,我该采用哪个方案?
大概答案:
无论是基于java语言还是python语言开发的现有框架的设计都是基于ORM设计的,就是说数据自动映射对象,在业务开发过程中,任何操作也都是基于对象操作,这才符合ORM原则。
像java相关的:Mybatis, JPA, springJDBC,像python相关的:django,这些框架涉及的数据库操作都是基于ORM。
如果我们想直接获取表数据,一般原生的JDBC即sql语句是可以实现的,但这不是基于对象操作,不符合ORM原则。
所以说,方案1和方案2其实都可以采用,但从对象操作的角度来看,主流都是采用方案1。
 
 

3.1.1.第一步:我们可以打印出可迭代对象的值是什么。

3.1.2.第二步:查询方法【all()】的具体使用。

细节:

①.相关源码如下:

def search_person(request):
'''1.通过方法all()间接获取到hello_person表里的三个表字段id,name,age的所有数据'''
# 第一步:新增三个数据类型为str的变量,初始值都设置为空,用于后续存储数据;
ids = ''
names = ''
ages = ''
# 第二步:通过调用方法all(),返回一个数据类型为可迭代对象QuerySet的变量res;
res = Person.objects.all()
# 第三步:通过for循环,获取我们想要的数据;
for i in res:
ids = ids + " " + str(i.id) # 我们把表字段id的值都存储在变量ids;
names = names + " " + i.name # 我们把表字段name的值都存储在变量names;
ages = ages + " " + str(i.age) # 我们把表字段age的值都存储在变量ages; # 第四步:把数据返回给前端页面;
return HttpResponse('''
表字段id所有的值汇总:%s;<br/>
表字段name所有的值汇总:%s;<br/>
表字段ages所有的值汇总:%s;<br/>
'''%(ids,names,ages))

3.2.查询方法【filter()】如何使用的完整记录

细节:

①.首先,我们知道查询一张数据表【hello_person】里的符合条件的数据的原生sql语句一般比如是:select * from hello_peroson where id = 9。

②.我们通过ORM框架提供的【filter()】方法也可以快速实现①的功能。

③.【filter() 】方法的返回值是一个可迭代对象QuerySet类型数据,该类型数据类似于list。这个可迭代对象QuerySet类型数据里面每个数据都是模型类的对象。

3.2.1.第一步:查询方法【fliter()】的具体使用。

细节:

①.方法fiter()的传参规则。

3.3.查询方法【exclude()】如何使用的完整记录

细节:

①.【exclude() 】方法的返回值也是一个可迭代对象QuerySet,返回值都是不符合查询条件的数据。

②.【exclude() 】方法在实际开发中基本少用,基本都采用【filter()】方法。

②.【exclude() 】方法的返回值是一个可迭代对象QuerySet类型数据,该类型数据类似于list。这个可迭代对象QuerySet类型数据里面每个数据都是模型类的对象。

3.3.1.第一步:查询方法【exclude()】的具体使用。

3.4.查询方法【order_by()】如何使用的完整记录

细节:

①.【order_by() 】方法的返回值也是一个可迭代对象QuerySet,返回值都是符合排序条件的数据。

②.【order_by() 】方法的返回值是一个可迭代对象QuerySet类型数据,该类型数据类似于list。这个可迭代对象QuerySet类型数据里面每个数据都是模型类的对象。

③.入参的相关注意点:

  • 参数的字段名要加引号。
  • 如果要实现降序功能,要在字段名前面加个负号【-】。

3.4.1.第一步:查询方法【order_by()】的具体使用。

3.5.查询方法【reverse()】如何使用的完整记录

细节:

①.【reverse() 】方法的返回值也是一个可迭代对象QuerySet,【reverse() 】方法用于对查询结果进行反转。

②.【reverse() 】方法在实际开发中基本少用,基本都采用【order_by()】方法。

③.【reverse() 】方法的返回值是一个可迭代对象QuerySet类型数据,该类型数据类似于list。这个可迭代对象QuerySet类型数据里面每个数据都是模型类的对象。

3.5.1.第一步:查询方法【reverse()】的具体使用。

3.6.查询方法【values()】如何使用的完整记录

细节:

①.【values() 】方法的返回值也是一个可迭代对象QuerySet,【values() 】方法用于查询部分字段或者全部字段的数据。

②.如果要查询全部字段的数据,【values() 】方法的入参字段数要为0;

③.【values() 】方法的返回值是一个可迭代对象QuerySet类型数据,该类型数据类似于list。这个可迭代对象QuerySet类型数据里面每个数据都不是模型类的对象而是可迭代的字典噢,字典里的键是表字段,值是表字段对应的数据。

3.6.1.第一步:查询方法【values()】的具体使用。

3.7.查询方法【values_list()】如何使用的完整记录

细节:

①.【values_list() 】方法的返回值也是一个可迭代对象QuerySet,但【values_list() 】方法用于查询部分字段或者全部字段的数据。

②.如果要查询全部字段的数据,【values_list() 】方法的入参字段数要为0;

③.【values_list() 】方法的返回值是一个可迭代对象QuerySet类型数据,该类型数据类似于list。这个可迭代对象QuerySet类型数据里面每个数据都不是模型类的对象而是元祖哦,元组里放的是查询表字段对应的数据。

3.7.1.第一步:查询方法【values_list()】的具体使用。

3.8.查询方法【distinct()】如何使用的完整记录

细节:

①.【distinct()】方法的返回值也是一个可迭代对象QuerySet。

②.【distinct()】方法的返回值是一个可迭代对象QuerySet类型数据,该类型数据类似于list。这个可迭代对象QuerySet类型数据里面每个数据都不是模型类的对象,而是每个元祖,元组里放的是查询字段对应的数据。

③.【distinct()】方法对模型类的对象去重没有意义,因为每个对象都是一个不一样的存在。所以【distinct()】方法一般是跟 【values】方法 或者 【values_list】方法 一起使用,但如果跟【all()】方法一起使用是产生不了去重的效果。

④.【distinct()】方法的作用:用于对数据进行去重。

3.8.1.第一步:查询方法【distinct()】的具体使用。

4.方法返回值是单个对象的每个查询方法的如何使用的完整记录

4.1.查询方法【get()】如何使用的完整记录

细节:

①.【get()】方法的返回值是一个模型类的对象。

②.【get()】方法用于查询符合条件的返回模型类的对象且符合条件的对象只能为一个,如果符合筛选条件的对象超过了一个或者没有一个都会抛出错误。

4.1.1.第一步:查询方法【get()】的具体使用。

4.2.查询方法【first()】如何使用的完整记录

细节:

①.【first()】方法返回符合查询条件的结果里的第一条数据且返回的数据是模型类的对象。

4.2.1.第一步:查询方法【first()】的具体使用。

4.3.查询方法【last()】如何使用的完整记录

细节:

①.【last()】方法返回符合查询条件的结果里的最后一条数据且返回的数据是模型类的对象。

4.3.1.第一步:查询方法【last()】的具体使用。

5.方法返回值是布尔值的每个查询方法的如何使用的完整记录

5.1.查询方法【exists()】如何使用的完整记录

细节:

①.【exists()】方法用于判断查询的结果 QuerySet 列表里是否有数据。

②.【exists()】方法返回值的数据类型是布尔值,有数据则返回值为true,没有数据则返回值为false。

5.1.1.第一步:查询方法【get()】的具体使用。

6.方法返回值是数字的每个查询方法的如何使用的完整记录

6.1.查询方法【count()】如何使用的完整记录

细节:

①.【count()】方法用于查询数据的数量且返回的数据是整数。

6.1.1.第一步:查询方法【count()】的具体使用。

7.相关的学习资料地址

①.django的ORM框架提供的查询数据库表数据的所有方法具体使用,可以查看该菜鸟教程地址:https://www.runoob.com/django/django-orm-1.html

django学习-15.ORM查询方法汇总的更多相关文章

  1. Django 学习 之ORM聚合查询分组查询与F查询与Q查询

    一.聚合查询和分组查询 1.聚合查询aggregate 关于数据表的数据请见上一篇:Django 学习 之ORM多表操作(点我) aggregate(*args, **kwargs),只对一个组进行聚 ...

  2. Django框架 之 ORM查询操作详解

    Django框架 之 ORM查询操作详解 浏览目录 一般操作 ForeignKey操作 ManyToManyField 聚合查询 分组查询 F查询和Q查询 事务 Django终端打印SQL语句 在Py ...

  3. DRF框架中链表数据通过ModelSerializer深度查询方法汇总

    DRF框架中链表数据通过ModelSerializer深度查询方法汇总 一.准备测试和理解准备 创建类 class Test1(models.Model): id = models.IntegerFi ...

  4. Django学习手册 - ORM 数据创建/表操作 汇总

    ORM 查询的数据类型: QuerySet与惰性机制(可以看作是一个列表) 所谓惰性机制:表名.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它 ...

  5. Django学习之ORM操作

    一.一般操作 二.必知必会13条 返回QuerySet对象的方法有 特殊的QuerySet 返回具体对象的 返回布尔值的方法有 返回数字的方法 三.单表查询之神奇的双下划线 四.ForeignKey操 ...

  6. Python - Django - ORM 查询方法

    models.py: from django.db import models class Human(models.Model): id = models.AutoField(primary_key ...

  7. Python Django中一些少用却很实用的orm查询方法

    一.使用Q对象进行限制条件之间 "或" 连接查询 from django.db.models import Q from django.contrib.auth.models im ...

  8. Django 一些少用却很实用的orm查询方法

    一.使用Q对象进行限制条件之间 "或" 连接查询 from django.db.models import Q from django.contrib.auth.models im ...

  9. Django学习手册 - ORM 多对多表

    定义表结构: class Host(models.Model): hostname = models.CharField(max_length=32) port = models.IntegerFie ...

随机推荐

  1. 使用C#实现数据结构堆

    一. 堆的介绍: 堆是用来排序的,通常是一个可以被看做一棵树的数组对象.堆满足已下特性: 1. 堆中某个节点的值总是不大于或不小于其父节点的值 任意节点的值小于(或大于)它的所有后裔,所以最小元(或最 ...

  2. 解决 error MSB4057: 该项目中不存在目标“_CopyWebApplication” 问题

    在使用MSBuild 编译项目的时候报错: 解决办法: 在Web项目中,使用Nuget添加引用  MSBuild.Microsoft.VisualStudio.Web.targets 即可.

  3. c语言实现--带头结点单链表操作

    可能是顺序表研究的细致了一点,单链表操作一下子就实现了.这里先实现带头结点的单链表操作. 大概有以下知识点. 1;结点:结点就是单链表中研究的数据元素,结点中存储数据的部分称为数据域,存储直接后继地址 ...

  4. Educational Codeforces Round 102 (Rated for Div. 2) B. String LCM (构造,思维)

    题意:给你两个字符串\(a\)和\(b\),找出它们的\(lcm\),即构造一个新的字符串\(c\),使得\(c\)可以由\(x\)个\(a\)得到,并且可以由\(y\)个\(b\)得到,输出\(c\ ...

  5. Codeforces Round #680 (Div. 2, based on Moscow Team Olympiad) C. Division (数学)

    题意:有两个数\(p\)和\(q\),找到一个最大的数\(x\),使得\(p\ mod\ x=0\)并且\(x\ mod\ q\ne 0\). 题解:首先,如果\(p\ mod\ q\ne0\),那么 ...

  6. C# Dictionary(字典)源码解析&效率分析

    通过查阅网上相关资料和查看微软源码,我对Dictionary有了更深的理解. Dictionary,翻译为中文是字典,通过查看源码发现,它真的内部结构真的和平时用的字典思想一样. 我们平时用的字典主要 ...

  7. CF1462-E2. Close Tuples (hard version)

    本题为hard版,还有一个easy版,区别在于k和m的取值不同. 题意: 给出一个由n个数字组成的数组 \(a\).现在定义一种子集为\(\{A_1, A_2, A_3, ..., A_m\}\),使 ...

  8. kubernetes实战-配置中心(二)交付apollo配置中心到k8s

    apollo官网:官方地址 apollo架构图: apollo需要使用数据库,这里使用mysql,注意版本需要在5.6以上: 本次环境mysql部署在10.4.7.11上,使用mariadb:10.1 ...

  9. UML类图设计神器 AmaterasUML 的配置及使用

    最近写论文需要用到UML类图,但是自己画又太复杂,干脆找了个插件,是Eclipse的,也有IDEA的,在这里我简单说下Eclipse的插件AmaterasUML 的配置与使用吧. 点击这里下载Amat ...

  10. volatile的内存屏障的坑

    请看下面的代码并尝试猜测输出: 可能一看下面的代码你可能会放弃继续看了,但如果你想要彻底弄明白volatile,你需要耐心,下面的代码很简单! 在下面的代码中,我们定义了4个字段x,y,a和b,它们被 ...