一、聚合查询:aggregate(*args, **kwargs)

  1. aggregate()QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。

    # 计算所有图书的平均价格
    from django.db.models import Avg
    Book.objects.all().aggregate(Avg('price'))
    # {'price__avg': 34.35}
    # 键的名称是按照字段和聚合函数的名称自动生成出来的。
    # 你也可以为聚合值指定一个名称,并向聚合子句提供它。
    Book.objects.aggregate(average_price=Avg('price'))
  2. 如果你希望生成不止一个聚合,你可以向aggregate()子句中添加另一个参数。所以,如果你也想知道所有图书价格的最大值和最小值,可以这样查询:

    from django.db.models import Avg, Max, Min
    Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
    # {'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}

二、分组查询:annotate() 

  1. 为调用的QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数)。

    a、统计每一本书的作者个数

bookList=Book.objects.annotate(authorsNum=Count('authors'))
for book_obj in bookList:
print(book_obj.title,book_obj.authorsNum)

    annotate的返回值是querySet,如果不想遍历对象,可以用上valuelist:

queryResult= Publish.objects.annotate(MinPrice=Min("book__price")).values_list("name","MinPrice")
print(queryResult)

三、select_related()

  1. select_related主要针一对一和多对一关系进行优化。
  2. select_related使用SQL的JOIN语句进行优化,它会自动查询出与之关联的表里的字段,一起做为查询结果,
  3. select_related不传任何参数的时候,默认会查询所有的关联对象,且会递归INNER JOIN所有的非空外键!!!
  4. select_related提供了关键字参数depth,默认为0,即递归直到最后一个对象没有非空外键为止。depth为1时只递归一级外键,以此类推。如果要访问指定深度外的字段,Django会再次进行SQL查询。
  5. 也接受无参数的调用,Django会尽可能深的递归查询所有的字段。但注意有Django递归的限制和性能的浪费。
  6. Django >= 1.7,链式调用的select_related相当于使用可变长参数。Django < 1.7,链式调用会导致前边的select_related失效,只保留最后一个

四、prefetch_related()

  1. 对于多对多字段(ManyToManyField)和一对多字段,可以使用prefetch_related()来进行优化。
  2. prefetch_related()和select_related()的设计目的很相似,都是为了减少SQL查询的数量,但prefetch_related()的解决方法是通过分别获取各个表的内容,然后用Python处理他们之间的关系来进行优化。
  3. 可以通过传入None来清空之前的prefetch_related。

五、extra

  1. 有些情况下,Django的查询语法难以简单的表达复杂的 WHERE 子句,对于这种情况, Django 提供了 extra() QuerySet修改机制 ,它能在 QuerySet生成的SQL从句中注入新子句
  2. extra可以指定一个或多个 参数,例如 selectwhere or tables. 这些参数都不是必须的,但是你至少要使用一个!要注意这些额外的方式对不同的数据库引擎可能存在移植性问题.(因为你在显式的书写SQL语句),除非万不得已,否则尽量避免这样做
    • 参数之select:                                                                                                                                                                                                                                                                                     select 参数可以让你在 SELECT 从句中添加其他字段信息,它应该是一个字典,存放着属性名到 SQL 从句的映射。

      queryResult=models.Article
                 .objects.extra(select={'is_recent': "create_time > '2017-09-05'"})

      结果集中每个 Entry 对象都有一个额外的属性is_recent, 它是一个布尔值,表示 Article对象的create_time 是否晚于2017-09-05.

    • 参数之where / tables:

      您可以使用where定义显式SQL WHERE子句 - 也许执行非显式连接。您可以使用tables手动将表添加到SQL FROM子句。

      wheretables都接受字符串列表。所有where参数均为“与”任何其他搜索条件。

      举例来讲:

      queryResult=models.Article
                 .objects.extra(where=['nid in (1,3) OR title like "py%" ','nid>2'])

六、bulk_create()

  1. 整体插入:

    创建对象时,我们看可以通过使用bulk_create()来批量增加记录。例如:

    Entry.objects.bulk_create([
    Entry(headline="Python 3.0 Released"),
    Entry(headline="Python 3.1 Planned")
    ])

七、defer

  有时候一个实体有过多的字段,取实体或者实体列表的时候,占用了多大的内存,而你却不需要取出全部的字段,比如博客的正文内容,你不需要立即检索数据库,这时defer就是你需要的东西。defer函数与前面讲的values有区别的,前者返回的是ValuesQuerySet,而defer返回的是QuerySet对象,这意味着,使用了defer后,你还可以结合QuerySet其他的函数,让整个语句结合更多的条件;

八、only

  only和defer是同一类的东西,可以理解为defer的相反函数。比如Person实体里有三个字段:name age birthday,下面这两条语句是等价的:

  1)Person.objects.defer("age", "biography")

  2)Person.objects.only("name")

ORM进阶操作的更多相关文章

  1. Django中的ORM进阶操作

    Django中的ORM进阶操作 Django中是通过ORM来操作数据库的,通过ORM可以很easy的实现与数据库的交互.但是仍然有几种操作是非常绕也特别容易混淆的.于是,针对这一块,来一个分类总结吧. ...

  2. ORM 进阶操作

    ORM多表操作 一.创建模型 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息:作者详情模型和作者模型之间是一对一的关系. 出版商模型:出版商有 ...

  3. web框架-(七)Django补充---models进阶操作及modelform操作

    通过之前的课程我们可以对于Django的models进行简单的操作,今天了解下进阶操作和modelform: 1. Models进阶操作 1.1 字段操作 AutoField(Field) - int ...

  4. Django orm进阶查询(聚合、分组、F查询、Q查询)、常见字段、查询优化及事务操作

    Django orm进阶查询(聚合.分组.F查询.Q查询).常见字段.查询优化及事务操作 聚合查询 记住用到关键字aggregate然后还有几个常用的聚合函数就好了 from django.db.mo ...

  5. django 2 ORM操作 ORM进阶 cookie和session 中间件

    ORM操作 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用描述 ...

  6. Django之Models进阶操作(字段属性)

    字段属性详细介绍 一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bigint自增列, ...

  7. ORM进阶之Hibernate 的三大对象

    ORM进阶之 ORM简单介绍 ORM进阶之Hibernate 简单介绍及框架搭 ORM进阶之Hibernate 的三大对象 我们在上一篇博客中讲到了怎样搭建一个Hibernate框架, 提到Hiber ...

  8. Django 之models进阶操作

    到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行数据库操作 ...

  9. Django ORM models操作

    title: Django ORM models操作 tags: Django --- Django ORM models操作 Django ORM基本操作 一.数据库的创建及增删改查 1 使用类创建 ...

随机推荐

  1. HDFS源码分析三-DataNode实现

    3. DataNode 实现( 未完待续 )

  2. 18.Consent 实现思路介绍

    讲一下实现Consent的逻辑 interaction它会根据returnUrl 输入用户名和密码后是在登陆的Controller,登陆完之后呢,会有一个returnUrl returnurl会被带到 ...

  3. java 关于getProperty()方法中反斜杠问题

    问: 在配置文件a.properties中有一行path=C:\test在java中getProperty("path")后,java把\t认为是一个字符TAB.怎样才能取到正确的 ...

  4. web前端_Vue框架_设置浏览器上方的标题和图标

    在创建Vue项目时一般会用默认的项目标题和图标,如下图所示: 不是很美观也可能不符合项目的需求,所以有时候就需要改变项目在浏览器上方的标签名称或者图标. 找到项目根目录的index.html,如图: ...

  5. TP5之使用layui分页样式

    1.首先你得引入layui文件吧 2.在 application\config.php 中配置,像这样,,, 3.controller中这样写 $data = Db::table($table) -& ...

  6. CodeForces722C Destroying Array【瞎搞】

    题意: 先给你一个序列,然后给你n个1-n的一个数,让你求前i个元素销毁的时候,区间字段和区间最大: 思路: 离线处理,维护新区间首尾位置的起点和终点,倒着处理: #include <bits/ ...

  7. builtin_shaders-5.3.4f1学习-Sprites-Default

    Shader "Sprites/Default" { Properties { [PerRendererData] _MainTex ("Sprite Texture&q ...

  8. 如何在内网打洞使得能暴露mstsc端口

    说明: 1.目标机器Target,有全部控制权,其所处网络无法向外网暴露端口,但是已知Target的外网地址:Target_internet_addr 2.交换机器Exchange,有全部控制权,其所 ...

  9. 洛谷 P4704 太极剑【贪心】

    首先考虑分割线能分割一条线当且仅当分割线一个端点在这条线的ab中间,另一端点在外面,也就是分割线对应的一条弧不能同时有这条线的两个端点 每条线的两端点都染同色,然后分段,一段里面颜色互不相同,分割线就 ...

  10. bzoj 2502: 清理雪道【有上下界有源汇最小流】

    对于原有边,流区间是(1,inf),按着原边连,然后再连(s,i,(0,inf)),(i,t,(0,inf))表示任意位置进出雪场 按着这个建出新图 然后最小流的方法是先跑可行流,设ans为(t,s, ...