推广 热搜:   企业  系统  中国  行业  公司  教师  设备    服务 

Django lazy load 懒加载 倒序查询

   日期:2024-10-31     浏览:78    移动:http://xiaoguoguo.dbeile.cn/mobile/quote/103.html
###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') 等语句时。 #####  .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('id')’默认升序 ASC ####在order_by('-id')和order_by('-pub_time') 排序字段名前加 - 减号表示降序 DESC res = models.Article.objects.all().order_by('id') 按照id正向排序 res.reverse()[:5] 注意,这与Python 中从一个序列的末尾进行切片有点不一样。上面的例子将首先返回最后一个元素,然后是倒数第二个元素,依此类推。如果我们有一个Python序列,当我们查看list[-5:]时,我们将一下子得到倒数五个元素。Django不支持这种访问模型(从末尾进行切片),因为它不可能利用SQL高效地实现。 同时还要注意,reverse() 应该只在一个已经定义排序的QuerySet上调用(例如,在一个定义了默认排序的模型上,或者使用order_by()的时候)。如果QuerySet没有定义排序,调用reverse()将不会有任何效果 ###本来这片文章的起因就是作者在写一个查询语句,我只需要最后更新的10个数据。我就在想如果是用SQL语句很简单: 但是如果使用Query_set 来查询,不管我是正序还是倒序,都会返回巨大的数据量。就开始去了解Django的Query_set 查询策略

	

以上表为例

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()

Django lazy load 懒加载 倒序查询

- 通过.frist()访问第一个元素,.last()访问最后一个元素. models.Article.objects.all().last()

根据 model 的 'get_latest_by' 选项或可选的字段名参数返回最新的对象. 例子:
Article.objects.latest()
Article.objects.latest('expire_date')

如果模型的meta指定get_latest_by,则可以将field_name参数留给earliest()或者 latest()。默认情况下,Django将使用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))

SELECT ... WHERe pub_date BETWEEN '2005-01-01' and '2005-03-31';

year、month、day

year: 返回精确的年份

Entry.objects.filter(pub_date__year=2005)

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)

本文地址:http://xiaoguoguo.dbeile.cn/quote/103.html    多贝乐 http://xiaoguoguo.dbeile.cn/ , 查看更多

特别提示:本信息由相关企业自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。


相关行业动态
推荐行业动态
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  鄂ICP备2023001713号