常用的QuerySet方法

  1、all()

    查询表中所有数据,返回一个QuerySet对象列表

  2、filter()

    查询满足条件的数据,返回一个QuerySet对象列表

  3、get()

    查询指定的数据(存在且唯一的数据)

    查询不到则报错,查询到多条数据也报错

  4、order_by("字段")

    将查询到的对象列表按照字段排序,默认是升序

    "-字段"为降序

    多字段排序order_by("字段1", "字段2")

      优先按照字段1排序,字段1相等的数据再按照字段排序

  5、reverse()

    对已经排好序的对象列表进行翻转(用在order_by后面)

  6、values()

    将对象列表转换为字典列表

    即[对象1,对象2...]《=============》[{对象1对应的数据字典},{对象2对应的数据字典}...]

    传入指定参数,可以指定字典中只存放指定的字段和值

  7、values_list()

    将对象列表转换为元组列表

    即[对象1,对象2...]《=============》[(对象1对应的所有数据的值),(对象2对应的所有数据的值)...]

    传入指定参数,可以指定元组中只存放指定字段的值

  8、distinct()

    去重,查询结果有重复值时去重

    如果是:

        id=1,name=a,age=18

        id=2,name=a,age=18

    则不会去重,因为这两条数据的id不同

    distinct不能传入指定参数去重

    只能够通过查询方法,查询指定字段的数据后将重复值去重

  9、count()

    计数,统计数据的个数

    效果和len()一样

    效率高于len(),推荐QuerySet使用count计数

  10、first()

    获取对象列表中的第一个对象

  11、last()

    获取对象列表中的最后一个对象

  12、exists()

    判断对象列表是否为空,布尔值

  13、exclude()

    获取不满足条件的对象列表

    与filter作用相反

单表的双下划线操作

  在对QuerySet做条件查询的时候,使用双下滑操作可以实现一些逻辑的操作

  比如:

    需要查询id值大于某个值的所有数据时,django是不允许使用 filter(id>10)这种形式的,这就需要用到双下划线操作

  1、小于某一个值(less than)

    字段名__lt = 10             <=====>    字段值<10

  2、大于(greater than)

    字段名__gt = 10          <=====>    字段值>10

  3、小于等于(less than equal)

    字段名__lte = 10          <=====>    字段值<=10

  4、大于等于(greater than equal)

    字段名__gte = 10          <=====>    字段值>=10

  5、大于等于  且  小于等于

    字段名__range = [1,10]            <=====>    1<=字段值<=10

    range表示取一定区间内的值,左右均能取到(和python语法中的range不同,这里的10是可以取到的)

  6、成员判断

    字段名__in = [1,2,3,4,5]

    这里的列表和 5 中的列表不同,5中的列表只接受两个值,表示一个区间范围

    这里的列表可以存放多个值,条件判断的结果是满足成员判断的结果(即查询出来的结果只能是出现在列表中的)

  7、字符串包含匹配

    a、区分大小写

      字段名__contains = "test"

      匹配结果的改字段中必须包含test,如test01、01test、01test01均可被匹配到

    b、不区分大小写  ( i表示ignore )

      字段名__icontains = "test"

      匹配结果的改字段中可以包含test或者TEST,如Test01、01TeSt、01test01均可被匹配到

  8、字符串匹配以指定字符开头或者结尾

    a、区分大小写

      字段名__startwith = "xxx"

      字段名__endwith = "xxx"

    b、不区分大小写

    字段名__istartwith = "xxx"

    字段名__iendwith = "xxx"

  9、对于日期类型的字段匹配

    字段__year = "2020"      获取2020年的所有数据

    字段__month = "1"   获取1月份的所有数据(查询结果可能为空,即使有相关数据)

    字段__day = "1"   获取1日的所有数据(查询结果可能为空,即使有相关数据)

    还可以用字符串方式匹配:

      字段__contains = "2020-1-1"   获取2020年1月1日的数据

      字段__contains = "-1-"  获取1月份的数据

  10、获取指定字段为空的数据

    字段__isnull = True

    注意:空字符串并不是null,null是初始化时为空

    

外键相关查询操作

  这里,简单举个1对多的关系:班级(1)和学生(多)的关系

  此时创建表时,外键字段(cls)自然就设置在学生表中

  1、基于对象的查询

    a、正向查询(通过外键字段进行的查询,即1:n关系中n的那一方的对象查询1的那一方的对象)

      通过一个学生对象,要想获取对应的班级信息:

      student_obj.cls,即可获取到对应的班级对象

    b、反向查询(通过对方的类名小写的方式查询,即1:n关系中1的那一方的对象查询n的那一方的对象。此时己方表中并没有对方的相关字段)

      通过一个班级对象,要想获取对应的学生信息:

      cls_obj.students_set,即可获取一个关系管理对象(反向查询的一个媒介,set就是集合的意思)

      cls_obj.students_set.all(),即可获取到当前班级对象对应的所有学生对象(返回一个对象列表)

    

    补充:关系管理对象的名称可以修改(如果不想使用  类名小写_set的形式获取关系管理对象)

      在定义外键字段的时候,可以加上参数related_name = "",指定一个名称方便后续获取关系管理对象

      设置related_name以后,就无法通过  类名小写_set 形式获取关系管理对象了

  2、基于字段的查询

    a、正向查询

      根据外键字段信息查询

      如需要查询所有班级名称为1的学生:

      models.Students.objects.filter(cls__name="1")       这实际上是根据一个跨表查询的数据,来完成当前表的数据筛选

      另外一种方式:

      先查询一个名称为1的班级对象       cls_obj = models.Cls.objects.filter(name="1")

      再查询1班的所有学生                     models.Students.objects.filter(cls = cls_obj)

    b、反向查询

      通过学生名查询对应班级信息(此时班级表中没有学生的相关字段)  

      没有在外键指定 related_name时:

        models.Cls.objects.filter(students__name="test"),此时只能通过类名小写形式进行双下划线跨表操作

      在外键指定了related_name时:

        models.Cls.objects.filter(这里换成指定的名称__name="test")       指定了related_name就只能用它查询,否则报错

      如果觉得related_name在查询时使用不方便:

        还以在外键中设置related_query_name指定一个查询时专用的名称,该名称只能用于查询字段时使用

        同时设置了related_name、related_query_name在字段查询时只能用后者,获取关系管理对象时只能用前者

多对多关系的查询操作

  多对多关系需要创建第三张表

  在django模型类的定义中,提供了一个便利操作,无需定义第三个类

  只需要在N:N关系的其中一方的模型类中定义一个ManytoMany字段即可,to参数可以是一个类名,也可以是类名的字符串形式(反射机制可以通过字符串拿到对应的类),ManytoMany字段和外键不同,它没有级联操作(delete on cascade等,更新数据需要在逻辑业务中实现)

  例如,书籍与作者的关系(n:n),假设ManytoMany字段定义在作者表中(book)

  1、基于对象的查询  

    a、通过作者对象获取对应的的书籍信息(正向查询,因为ManytoMany字段在作者表中)

      author_obj.book,此时获取到的依然是一个关系管理对象(与外键操作不同,外键操作中N的那一方直接通过外键字段获取到另一方的数据对象,是因为另一方是唯一确定的,而多对多关系中,双方获取对方信息的个数是不确定的)

    b、通过书籍对象获取对应的作者信息(方向查询,查询方式和外键操作中一致)

      book_obj.authors_set,作者类名_set的形式获取到关系管理对象,此时同样可以在ManytoMany字段中设置related_name修改关系管理对象的名称

  2、基于字段的查询

    和外键查询操作如出一辙

    同样可以设置ManytoMany字段中的related_query_name来修改字段查询的名称

  3、通过一个作者对象设置作者和书籍之间的对应关系

    author_obj.book,获取关系管理对象

    author_obj.book.set([ ])通过关系管理对象下的set方法,传入一个列表,列表中可以是多个书籍的的id或者书籍对象

    完成设置,即可将关系表中的对应关系修改完成

关系管理对象的方法

  1、all方法    获取该关系管理对象下的所有对象信息

  2、set方法   设置多对多关系(或者1对多关系)

    设置多对多关系时

      set方法接收的列表,可以是多个id值,也可以是多个对象

    设置1对多关系时,

      set方法接收的列表,只能是对象列表

  3、add方法  添加多对多关系(或者1对多关系)

    往关系表中新增数据,add方法接收可变长的位置参数,即add(*args)形式

    添加多对多关系时

      可以传入的是id,或者是对象

    添加1对多关系时

      只能传入对象

  4、remove  删除多对多关系(或者1对多关系)

    同样接收一个可变长的位置参数

    注:删除1对多关系时,需要将外键指定设置为null=True否则无法删除

  5、clear   清空关系表

    不接收任何参数

    注:清空1对多关系时,同样需要将外键指定设置为null=True否则无法清空

  6、create 新增一个对象,且和当前对象建立关系

    author_obj.books.create(name="测试")

    新增一本书《测试》存入书籍表,并且与当前作者建立关系,存入关系表中

聚合和分组

  1、django常用的内置聚合函数:

    form django.db.models import Max, Min, Count, Sum, Avg

    Max:最大值

    Min:最小值

    Count:计数

    Sum:求和

    Avg:求平均值

  对于QuerySet执行聚合操作需要用到聚合方法aggregate(),在聚合方法内使用相应的聚合函数即可

    对象列表.aggregate(Max("指定字段"))             求某个字段的最大值

    返回结果是一个字典:{"指定字段名__max": 对于的值},键名是由字段名  + 双下划线 + 相应聚合函数的小写组成

    如果想要指定字典中键的名称,可以将方法内函数写成关键字形式,如:对象列表.aggregate(max=Max("指定字段")),这样就指定了键的名称为max

  aggregate也称为终止子句,因为该方法返回的结果不再是QuerySet,因此后续无法再进行相关查询操作。

  

  2、分组(group by)

    分组使用到的方法:annotate

    统计每本书的作者个数:

    models.Book.objects.annotate(Count("authors"))

    models.Book.objects:表示按书进行分组

    Count("authors"):统计分组后每本书的作者个数,因为多对多字段定义在作者类中,所以Count指定的字段为作者表的小写(或者related_name如果指定了该属性的话)

    annotate:负责将统计的结果,作为属性值插入到每本书的对象中,然后返回一个对象列表

    

  annotate实现了分组的过程

    实际上将分组聚合后的结果添加到了每个分组的对象上

F查询和Q查询

  from django.db.models  import F,Q

  1、F查询

    获取比较同一张表中不同字段的结果

    F("字段"):获取当前对象中指定字段的值

    如获取书籍表中,库存大于销量的书

      models.Book.objects.filter(库存__gt=F("销量"))

      对应的sql:select book_name from books where 库存>销量

  

  2、Q查询,进行与(&)或(|)非(~)操作

    如获取id值大于5或者小于3的数据

    models.Book.objects.filter(Q(id__gt=5)| Q(id__lt=3))

事务

  from django.db import transaction

  执行事务:

    with transaction.atomic():

      # with内部执行一系列操作(要么都执行,要么都不执行)

  

  执行事务过程中 ,中途报错的话会触发回滚机制,之前的操作全部撤销

  为了不影响代码正常运行,需要进行异常捕获

  注意:异常捕获必须在with外部 ,也就是将整个with子句包括起来,才能正常执行事务

     如果在with内部进行异常捕获的,既然异常能够正确被处理,却无法触发回滚机制,异常发生前的所有操作不会被撤销。

django—ORM相关的更多相关文章

  1. Django学习笔记之Django ORM相关操作

    一般操作 详细请参考官方文档 必知必会13条 <> all(): 查询所有结果 <> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 <> ...

  2. Django ORM相关的一些操作

    一般操作 看专业的官网文档,做专业的程序员! 必知必会13条 <1> all(): 查询所有结果 <2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象 ...

  3. Django ORM相关

    1. ORM 外键关联查询和多对多关系正反向查询 Class Classes(): name = CF class Student(): name = CF class = FK(to="C ...

  4. Django框架详细介绍---ORM相关操作

    Django ORM相关操作 官方文档: https://docs.djangoproject.com/en/2.0/ref/models/querysets/ 1.必须掌握的十三个方法 <1& ...

  5. Django ORM那些相关操作zi

    Django ORM那些相关操作   一般操作 看专业的官网文档,做专业的程序员! 必知必会13条 <1> all(): 查询所有结果 <2> filter(**kwargs) ...

  6. Django ORM 那些相关操作

    Django ORM 那些相关操作 一般操作 必知必会13条 <> all(): #查询所有的结果 <> filter(**kwargs) # 它包含了与所给筛选条件相匹配的对 ...

  7. Django ORM那些相关操作

    一般操作 https://docs.djangoproject.com/en/1.11/ref/models/querysets/         官网文档 常用的操作 <1> all() ...

  8. django orm 及常用参数

    一些说明: 表myapp_person的名称是自动生成的,如果你要自定义表名,需要在model的Meta类中指定 db_table 参数,强烈建议使用小写表名,特别是使用MySQL作为后端数据库时. ...

  9. Django ORM中常用字段和参数

    一些说明: 表myapp_person的名称是自动生成的,如果你要自定义表名,需要在model的Meta类中指定 db_table 参数,强烈建议使用小写表名,特别是使用MySQL作为后端数据库时. ...

随机推荐

  1. js之按钮切换

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  2. 软件工程与UML作业1

    这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzzcxy/2018SE1 这个作业要求在哪里 https://edu.cnblogs.com/campus/fz ...

  3. Mysql数据分片技术(一)——初识表分区

    1. 为什么需要数据分片技术 2. 3种数据分片方式简述 3. 分片技术原理概述 4. 对单表分区的时机 1为什么需要数据分片技术 数据库产品的市场 在互联网行业内,绝大部分开发人员都会遇到数据表的性 ...

  4. Node.js 从零开发 web server博客项目[登录]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  5. mysql优化的常用方法

    mysql的优化,大体分为三部分:索引的优化,sql语句的优化,表的优化 1.索引的优化 只要列中含有NULL值,就最好不要在此列设置索引,复合索引如果有NULL值,此列在使用时也不会使用索引 尽量使 ...

  6. python基本语法要注意哪些?本文详解!

    基本语法 第一个注释 print("hello,python") # 第二行注释 string_demo = "你好!" string_demo print ( ...

  7. Java随谈(二)对空指针异常的碎碎念

    本文适合对 Java 空指针痛彻心扉的人阅读,推荐阅读时间25分钟. 若有一些Java8 函数式编程的基础可以当成对基础知识的巩固. 一.万恶的null 今天,我们简单谈谈null的问题.因为null ...

  8. 如何将炫酷的报表直接截图发送邮件——在Superset 0.37使用Schedule Email功能

    Superset的图表是非常炫酷的,但是原来的版本只能在web端查看,而最新的0.37版本,可以将图表截图直接发送成邮件,非常的方便. 本文将详细介绍Superset 0.37 定时邮件功能.安装过程 ...

  9. Egg.js学习

    egg.js是什么 是一个node.js的后台web框架,类似的还有express,koa 优势:规范.插件机制Egg.js约定了一套代码目录结构(配置config.路由router.扩展extend ...

  10. Android Studio 自定义字体显示英文音标

    android:fontFamily="serif" 网上查了很多自定义字体的方式,或多或少都有些麻烦,最后还是尝试着认为内置字体不应该实现不了英文音标问题,就一个一个字体试了一下 ...