Django lazy load 懒加载 倒序查询
###Django orm默认使用的懒加载,即使用的时候才去访问数据库,且每次默认取最少的数据,当然这样有好处也有坏处...
- ####坏处:
会导致频繁的查询数据库,如涉及到外键的时候,会先去取需要的数据集,再取外键的数据集,等于访问了两次数据库,那取n条数据就访问了n*n次数据库
如查询语句:
models.Article.objects.all() 当Article表中关联author、tag、categroy等外键字段时,你取一条数据,他需要去访问4次数据库,三外键加本身。
- ####好处:
显然的当你执行:
models.Article.objects.all() 这样的语句,如果一次全部查询把所有数据给你返回,你是小网站,数据小无所谓,数据大了内存就爆炸了!
####django orm的策略是,懒加载:
#####即:res = models.Article.objects.all()这样的所有查询、obj = models.Article('title'='xxx', 'body' = 'xxx') 等语句时。
#####并没有真正去数据库操作取出、生成数据,而是生成Query_set迭代对象
.create() 和.update()语句会保存的同时直接去数据库创建
而在执行res[0].title、res[10],body 还有obj.save()这样的语句时才真正的去执行SQL语句,操作数据库,取数据,保存数据。
第一个很直观的一堆Query_set对象中没有取回数据,当然占用内存就小很多了。
而当每次查询回来数据,Django就会把这些数据保存在cache中,当你下次使用时,不会去数据库再次查询,而是去cache里面取。
- ####结果集
Django 的数据查询基于构建结果集及对结果集进行取值. 结果集是独立于数据库的符合某个查询条件的一组数据对象的集合.这是一个惰性集合:在对该集合取值之前,无法知道该集合有哪些成员.
要生成一个满足你需求的结果集,首先要得到一个描述给定类型的所有对象的初始结果集.这个初始结果集可以通过一系列函数进行更精细的优化处理.当经过处理后的结果集符合你的要求时, 就可以对它进行取值操作(使用迭代操作,slicing操作,或一系列其它技术), 以得到一个你需要的对象或对象的列表.
获得初始结果集
每个 Django model 都有一个与生俱来的管理器对象 objects, 管理器最重要的角色就是作为初始结果的来源. 一个管理器就是一个描述给定类型所有对象的特殊的初始结果集. Article.objects 就是包含所有 Poll 对象的一个初始结果集. 它唯一特殊之处在于它不能被取值. 要克服此限制, 管理器对象有一个 all() 方法. 该方法生成一个 可以 被取值的初始结果集的拷贝:
res = models.Article.objects.all()
Article.objects.all()[:-11:-1] 取最后10个对象
Article.objects.all()[0:10] 取前10个对象
结果集对象是惰性对象 - 也就是说,他们不是 真正的 包含他们表示对象的集合 (或列表). Python 的协议魔法让结果集看起来是一个可迭代,可切片的对象. 事实上在幕后, Django 使用了缓存技术..
如非要把它们变成列表。那只能强制取值了:
querylist = list(Article.objects.all()) #这儿可以理解为 list(dict.keys())一样的感觉,把对象变为列表
不过,最好不要这么做,特别是在该集合相当大时. Django 每创建一个对象都需要内存,将占用相当大的内存.
可理解为生成器 genrator = (x for x in range(10000000)) 和列表生成式 list = [i for i in range(100000000)] 的区别
前者是一个生成器对象,当需要数据时,根据规则去生成,而后者是实实在在在内存中存在的大列表
####.order_by()语句 order_by('id')’默认升序 ASC
####在order_by('-id')和order_by('-pub_time') 排序字段名前加 - 减号表示降序 DESC
res = models.Article.objects.all().order_by('id') 按照id正向排序
- ####reverse()方法反向排序
res.reverse()[:5]
注意,这与Python 中从一个序列的末尾进行切片有点不一样。上面的例子将首先返回最后一个元素,然后是倒数第二个元素,依此类推。如果我们有一个Python序列,当我们查看list[-5:]时,我们将一下子得到倒数五个元素。Django不支持这种访问模型(从末尾进行切片),因为它不可能利用SQL高效地实现。
同时还要注意,reverse() 应该只在一个已经定义排序的QuerySet上调用(例如,在一个定义了默认排序的模型上,或者使用order_by()的时候)。如果QuerySet没有定义排序,调用reverse()将不会有任何效果
###本来这片文章的起因就是作者在写一个查询语句,我只需要最后更新的10个数据。我就在想如果是用SQL语句很简单:
但是如果使用Query_set 来查询,不管我是正序还是倒序,都会返回巨大的数据量。就开始去了解Django的Query_set 查询策略
from django.db import models
class Article(models.Model):
title = models.CharField(max_length= 64)
body = models.TextField()
pub_time = models.DateTimeField(auto_now_add= True)
class Meta:
get_latest_by = 'pub_time'
几种反向查询策略:以上表为例
order_by() 语句:
models.Article.objects.all().order_by('-id) 或者 order_by('-pub_time')
反向切片访问:
models.Article.objects.fiter(id__gte=0)[::-1] 完全反向切片
reverse()函数
models.Article.objects.all().order_by('id').reverse()
- 通过.frist()访问第一个元素,.last()访问最后一个元素.
models.Article.objects.all().last()
latest(self, *fields, field_name=None) 函数访问
根据 model 的 'get_latest_by' 选项或可选的字段名参数返回最新的对象. 例子:
Article.objects.latest()
Article.objects.latest('expire_date')
如果模型的Meta指定get_latest_by,则可以将field_name参数留给earliest()或者 latest()。默认情况下,Django将使用get_latest_by中指定的字段。
get_latest_by
由于Django的管理方法中有个lastest()方法,就是得到最近一行记录。如果你的数据模型中有 DateField 或 DateTimeField 类型的字段,你可以通过这个选项来指定lastest()是按照哪个字段进行选取的。
一个 DateField 或 DateTimeField 字段的名字. 若提供该选项, 该模块将拥有一个 get_latest() 函数以得到 "最新的" 对象(依据那个字段):
exact、iexact
exact:精确匹配。区分大小写
例如:
Entry.objects.get(id__exact=14)
Entry.objects.get(id__exact=None)
iexact:不区分大小写的精确匹配
例如:
Blog.objects.get(name__iexact='beatles blog')
Blog.objects.get(name__iexact=None)
contains、icontains
contains:包含,大小写敏感
例如:
Entry.objects.get(headline__contains='Lennon')
icontains:包含,大小写不明感.
例如:
Entry.objects.get(headline__icontains='Lennon')
in
在一个给定的列表中.
Example:
Entry.objects.filter(id__in=[1, 3, 4])
gt、gte、lt、lte
gt:大于
例子:
Entry.objects.filter(id__gt=4)
gte:大于或等于
lt:小于
lte:小于或等于
startswith、istartswith、endswith、iendswith
startswith:区分大小写,开始位置匹配
例如:
Entry.objects.filter(headline__startswith='Will')
istartswith:不区分大小写,开始位置匹配
endswith:区分大小写,结束位置匹配
iendswith:不区分大小写,结束位置匹配
range
范围
例如:
import datetime
start_date = datetime.date(2005, 1, 1)
end_date = datetime.date(2005, 3, 31)
Entry.objects.filter(pub_date__range=(start_date, end_date))
等价SQL:
SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';
year、month、day
year: 返回精确的年份
例如:
Entry.objects.filter(pub_date__year=2005)
等价SQL:
SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31';
month: 对于月份时间字段,匹配一个整数从1 (January)到 12 (December).
day: 对于日期和日期时间字段,具体到某一天的匹配。取一个整数的天数。
isnull
值为 True 或False, 相当于SQL语句IS NULL和IS NOT NULL.
例如:
Entry.objects.filter(pub_date__isnull=True)
等价SQL:
SELECT ... WHERE pub_date IS NULL;
Django lazy load 懒加载 倒序查询的更多相关文章
- django中的懒加载机制
懒加载在前端中的意义: 懒加载的主要目的就是作为服务器前端的优化,减少请求次数或者延迟请求数. 实现原理: 先加载一部分数据,当触发某个条件时利用异步加载剩余的数据,新得到的数据不会影响原有数据的显示 ...
- lazy图片懒加载使用
看到一个小伙子写的言简意赅很不错,摘录如下: https://www.npmjs.com/package/vue-lazyload 首先我们先在npm上下载vue-lazyload的包 1 npm i ...
- 后端查询树的通用SQL,具备懒加载功能
select t.org_id as key, --key值 t.org_name as title, --标题 t.has_sub as folder, --是否显示文件夹 t.has_sub as ...
- web进修之—Hibernate 懒加载(6)
关于懒加载 在关系数据库设计的时候,我们很多时候把表之间的关系设置为强关联(使用外键进行约束),在Hibernate中利用对象的包含关系进行维护(HIbernate本身就是面向对象的数据库操作模式), ...
- 解决hibernate中的懒加载(延迟加载)问题
解决hibernate中的懒加载(延迟加载)问题 我们在开发的时候经常会遇到延迟加载问题,在实体映射时,多对一和多对多中,多的一样的属性默认是lazy="true"(即,默认是 ...
- 20160510--hibernate懒加载问题
懒加载 通过asm和cglib二个包实现:Domain是非final的. 1.session.load懒加载. 2.one-to-one(元素)懒加载: 必需同时满足下面三个条件时才能实现懒加载 (主 ...
- 一步步学习NHibernate(5)——多对一,一对多,懒加载(2)
请注明转载地址:http://www.cnblogs.com/arhat 通过上一章的学习,我们建立了Student和Clazz之间的关联属性,并从Student(many)的一方查看了Clazz的信 ...
- Hibernate 性能优化之懒加载
针对数据库中的大数据,不希望特别早的加载到内存中,当用到它的时候才加载 懒加载分为:类的懒加载.集合的懒加载.单端关联的懒加载 类的懒加载 1.在默认情况下,类就是执行懒加载 2. ...
- mybatis中的懒加载
知识点:mybatis中的懒加载的使用 参考:https://www.cnblogs.com/ysocean/p/7336945.html?utm_source=debugrun&utm_me ...
随机推荐
- c/c++ 线性表之单向循环链表
c/c++ 线性表之单向循环链表 线性表之单向循环链表 不是存放在连续的内存空间,链表中的每个节点的next都指向下一个节点,最后一个节点的下一个节点不是NULL,而是头节点.因为头尾相连,所以叫单向 ...
- MySQL服务使用
MySQL服务使用 1. 启动服务 启动服务: service mysql start 或者 sudo /etc/init.d/mysql start 2. 关闭服务 关闭服务: service my ...
- Lua代码规范
以下规范,是在Unity中使用Lua做为开发语言,仅供参考. 1.格式规范 1. lua文件名统一小写,中间一律不加下划线分割 2. 类名首字母大写,多个词组成的类名,每个词的首字母大写,中间一律不加 ...
- Vue 学习笔记之快速入门篇
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅易于上手,还便于与 ...
- windows平台下实现高可用性和可扩展性-ARR和HLB
本文档提供了关于如何将应用程序请求路由(ARR)与硬件负载均衡器一起使用以实现高可用性和可伸缩性的说明性指导.本文采用F5大IP负载均衡器来说明ARR与硬件负载平衡器之间的工作关系. IIS7.0及以 ...
- FAT32格式和NTFS格式区别
NTFS(Windows):支持最大分区2TB,最大文件2TB: FAT16(Windows):支持最大分区2GB,最大文件2GB: FAT32(Windows):支持最大分区128GB,最大文件4G ...
- 聚类——FCM的matlab程序
聚类——FCM的matlab程序 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 在聚类——FCM文章中已介绍了FCM算法的理论知识,现在用matlab ...
- human pose estimation
2D Pose estimation主要面临的困难:遮挡.复杂背景.光照.真实世界的复杂姿态.人的尺度不一.拍摄角度不固定等. 单人姿态估计 传统方法:基于Pictorial Structures, ...
- Loj #2731 「JOISC 2016 Day 1」棋盘游戏
Loj 2731 「JOISC 2016 Day 1」棋盘游戏 JOI 君有一个棋盘,棋盘上有 \(N\) 行 \(3\) 列 的格子.JOI 君有若干棋子,并想用它们来玩一个游戏.初始状态棋盘上至少 ...
- Celery 异步任务
Celery https://www.cnblogs.com/DragonFire/p/10356615.html 介绍: Celery 是芹菜 Celery 是基于Python实现的模块, 用于执行 ...