the5fire的技术博客

关注python、vim、linux、web开发和互联网--life is short, we need python.


Django中的latest使用

作者:the5fire | 标签:     | 发布:2013-08-16 6:33 a.m. | 阅读量: 6429, 6321
晚上回来查了下latest的用法,发现白天在公司对这个功能的理解有误。以为这个只是跟时间有关,其实任何可以排序的东西都能用latest。

场景

有这样的一个场景,我需要取出最近发布的一篇文章,怎么做呢?最直观的做法就是

latest_post = Post.objects.filter(status=1).order_by('-id')[:1][0]

这么做是不是有点怪呢,尤其是最后的一个切片和一个取list总第一个值的操作。有没有更优雅的方案呢?

latest来了

名如其意,就是取最近的/最新的一个对象,注意是一个对象,而不是一个只包含一个元素的list。怎么用呢?

latest_post = Post.objects.filter(status=1).latest('id')

如此这般,这事就办了。并且充满了人类的气息,这就是所谓的语义化了。语义化的重要性不用多说了,某人牛曾说过: 代码是给人看的,丫碰巧能在机器上执行

sql层面一样吗

既然一个问题有了两种解决方案,那么这俩除了在语义上的区别还有什么区别,效率如何呢。先来看看他们生成的sql语句是怎样的。怎么查看呢?

对于Django的QuerySet对象来说,直接print其query属性即可得到这条语句执行的sql是什么。那么对于 latest 这不返回QuerySet对象的方法呢?其实可以在执行完语句之后 print connection.queries[-1]['sql'] 当然要先 from django.db import connection

用order_by执行的语句是 .. code:

SELECT `blog_post`.`id`, `blog_post`.`author_id`, `blog_post`.`category_id`, `blog_post`.`title`, `blog_post`.`alias`, `blog_post`.`is_top`, `blog_post`.`summary`, `blog_post`.`content`, `blog_post`.`content_html`, `blog_post`.`view_times`, `blog_post`.`tags`, `blog_post`.`status`, `blog_post`.`is_old`, `blog_post`.`pub_time`, `blog_post`.`create_time`, `blog_post`.`update_time` FROM `blog_post` WHERE `blog_post`.`status` = 1  ORDER BY `blog_post`.`id` DESC LIMIT 1

latest执行的语句是 .. code:

SELECT `blog_post`.`id`, `blog_post`.`author_id`, `blog_post`.`category_id`, `blog_post`.`title`, `blog_post`.`alias`, `blog_post`.`is_top`, `blog_post`.`summary`, `blog_post`.`content`, `blog_post`.`content_html`, `blog_post`.`view_times`, `blog_post`.`tags`, `blog_post`.`status`, `blog_post`.`is_old`, `blog_post`.`pub_time`, `blog_post`.`create_time`, `blog_post`.`update_time` FROM `blog_post` WHERE `blog_post`.`status` = 1  ORDER BY `blog_post`.`id` DESC LIMIT 1

一样的语句没有区别。

最后补充一点是,用latest是不延迟加载的。

Note

Django从1.6起有了last()这个方法,可以依据主键直接取出最新的那个id。 而latest Django1.2以上就有了,在Django1.6开始还有一个earliest可供使用。

参考


----EOF-----

扫码关注,或者搜索微信公众号:码农悟凡


其他分类: