转一篇:文档笔记之Django QuerySet

这个放着,说不定以后作一些更深入的查询时,用得着的。

 

http://www.rapospectre.com/blog/7/

今天刚刚答完辩体完检就跑来更新博客了!!!

先补上第一篇:

一般情况下,我们在写Django项目需要操作QuerySet时一些常用的方法已经满足我们日常大多数需求,比如get、filter、exclude、delete神马的感觉就已经无所不能了,但随着项目但业务逻辑越来越复杂,这几个方法可能就不能很好但满足我们了,所以这时候,最好的办法是神马??对,读文档!这里的读文档不是有业务需求时去查文档,而是要为了阅读文档而阅读文档。以下也是作为我的文档阅读笔记,我记下了一些我以后可能会用到或者一些技巧性提升的东西,好,不废话,正文开始:

首先,我们假设有以下两个model:

class Entry(Model.models):
    ip = models.CharField(max_length=20)
    time = models.DateTimeField()
    black = models.BooleanField(default=False)

class Blog(Model.models):
    title = models.CharField(max_length=100)
    content = models.CharField(max_length=500)
    publish = models.BooleanField(default=False)
    entry = models.ForeignField(Entry, relate_name='entrys')

1、annotate(args, *kwargs)

为queryset增加注解,神马是注解?就是你读出queryset可能会需要一些额外数据要添加进去的时候,你就可以用这个东东咯,使用方法看代码:

>>> q = Blog.objects.annotate(Count('entry'))
# The name of the first blog
>>> q[0].name
'Blogasaurus'
# The number of entries on the first blog
>>> q[0].entry__count
42

Blog model 类本身并没有定义 entry__count 属性,但可以使用注解函式的关系字参数,从而改变注解的命名:

>>> q = Blog.objects.annotate(number_of_entries=Count('entry'))
# The number of entries on the first blog, using the name provided
>>> q[0].number_of_entries
42

2、aggregate(args, *kwargs) 这个参数有点像annotate的反义,annotate返回的是一个包含注解值的queryset,而aggregate则单独返回注解值,返回类型是一个dict,当然,这种方式在文档中叫做聚合查询,具体使用如下:

>>> q = Blog.objects.aggregate(Count('entry'))
{'entry__count': 16}

通过在 aggregate 指定关键字参数,你可以控制返回的聚合名称:

>>> q = Blog.objects.aggregate(number_of_entries=Count('entry'))
{'number_of_entries': 16}

3、defer(*fields) 延后读取字段。啥意思?我读文档时就这感觉。。后来发现是酱紫滴,一个复杂滴model可能你从数据库中读出后根本不需要某些字段,读了又浪费时间浪费空间,怎么办?对!用defer,延后读取,你可以在defer中指定一个或多个字段,也可用链式方法使用defer,它返回对依然是个完整对queryset但其中defer指定但字段并没有真但从数据库读出来,只有当你访问这些延后字段时django才会从数据库读取这些数据,感觉在数据量变大后用这个方法很nice,具体用法如下:

Blog.objects.defer("content").filter(publish=True).defer("title")

不过要注意的是,不能用defer过的字段进行order_by操作,这样做木有作用滴,如果需要清楚defer,只要加个defer(None)就ok啦。

你还阔以defer model中的外键,但是你需要提使用 select_related() 载入关联 model,具体用法:

Blog.objects.select_related().defer("entry__ip", "entry__time")

4、only(*fields) 我想你已经猜到了,一定是defer相反的咯,是啊是啊,没错。only会立即查询指定的字段,但是要注意了,这有坑,only只返回指定的字段,其他木有指定的默认就给defer了哟,所以以下写法是等价滴:

Entry.objects.only('ip')
Entry.objects.defer('time', 'black')

当你使用链式方法调用only时只有最后一个only内的参数会立即返回,其他参数都会被defer,注意这里only的覆盖性~

5、create(**kwargs) 创建并保存对象。一般我们要新建一个model对象时直接使用他的构造函数或者使用.语法赋值,最后调用.save()方法保存。那么在我们已经知道新建这个对象所有必须数据的情况下,其实用create会更快捷,代码看着更干净,起使用方法与构造方法类似,只是不需要调用.save()啦, 例子如下:

p = Entry.objects.create(ip='127.0.0.1', time=<a datetime type object>, black=False)

6、get_or_create(kwargs) 和 update_or_create(kwargs)

嗯,看看就知道这个是create的升级版,没错,他们俩一个是在查无此数据后新建一个是更新不存在数据时新建,具体用法同createget_or_create等效如下过程:

try:
    obj = Blog.objects.get(title='test', content='test')
except Blog.DoesNotExist:
    obj = Blog(title='test', content='test')
    obj.save()

注意这两个方法的返回值,他们返回两个东东:

 created, obj = get_or_create(**kwargs)

其中created是个bool值,当此方法生成了一个新的model object,此值为True,反之为False,obj则是生成的object或者查到的object实例。

7、latest(field_name=None) 和 earliest(field_name=None) 分别返回指定字段的最新数据与最早数据。

8、first() 和 last() 分别返回queryset的第一项与最后一项,具体用法如下:

p = Blog.objects.order_by('title').first()

等同于:

try:
    p = Blog.objects.order_by('title')[0]
except IndexError:
    p = None

9、update(**kwargs) 用于更新一组数据,但要注意,它不能更新外键, 不能更新切片过的queryset以及不能再被切片的set,用法如下:

Entry.objects.filter(black=False).update(ip='0.0.0.0')

10、delete() 有人肯定要说了,博主你再逗我,这个方法抬头不见低头见,还用你说?!是啊是啊,删除普通数据的时候当然木有什么,但是如果删除外健关系很复杂的object时有木有想过细节?是不是细思极恐 啊#_# 比如,以我们开头的model为例,我删了一个entry实例,那么与它有外健关联的blog实例会怎样?一同被删了?还是保留?保留的话那他对应的entry外健是神马?WTF! 嗯,实话告诉你,默认情况下调用delete()是会删除所有有关的外键对象的(是不是突然感觉自己之前代码里有坑了)所以我们需要详细说说这个方法,如何做才能让他不删除对应的外键或者说按照我们想象的方式进行删除呢?

答案在这里:

django.models 的on_delete参数,此参数有以下几个可选值:

  • CASCADE:这就是delete()的默认选项,也就是关联删除
  • PROTECT:如果删除的model obj含有外键则引起 ProtectedError
  • SET_NULL:就是把外键置空咯,当然前提是你得设置外键的null=True
  • SET_DEFAULT:就是把外键设为默认咯,当然前提是你得设置外键的default=xxx
  • SET():SET内应是一个函数,用来返回一个外键实例,用法如下:
    def get_sentinel_user():
        return get_user_model().objects.get_or_create(username='deleted')[0]
    
    class MyModel(models.Model):
        user = models.ForeignKey(settings.AUTH_USER_MODEL,
                                 on_delete=models.SET(get_sentinel_user))

11、fields lookups 强大滴django fields lookups,具体可选参数有:

iexact icontains in istartwith gt gte lt lte endwith iendwith range year month day week_day hour minute second insole (ex: search) iregex

其中,首字母带“i”的意思就是不分大小写,如果需要大小写敏感就把“i”去掉啦~其他参数大体从字面意思就知道啦,改天补上详细的�例子。

12、Avg、Count、Sum、Max、Min、StdDev、Variance 这些方法就是求数据的相应结果咯,比如avg就是平均值啦,嗯,基本都看得懂,除了后两个,一个是方差,一个是标准差,具体用法其实前文里有,我还是放一下:

q = Blog.objects.annotate(Count('entry'))

13、强大的Q查询与F查询: 嗯,这一部分先留着,总之告诉你很腻害就是了,可以做很复杂的查询,先放个例子:

q = Blog.objects.filter(Q(title='test')|Q(content='hahaha'))

这是一个或查询,满足其中一个条件的数据会被返回。

好,我们下期再见(对,博主懒病犯了,反正也没人看2333333)

时间: 2024-11-02 12:24:48

转一篇:文档笔记之Django QuerySet的相关文章

打开Word时提示“无法注册这篇文档”的解决办法

如果DCOM Server Process Launcher服务被禁用,启动Word时将出现"无法注册这篇文档,不能创建从其它文档到这篇文档的链接"的提示框. 方法一: 1.单击左下角的"开始"按钮,弹出的菜单窗口单击"运行"命令 2.在打开的"运行",对话框中输入"services.msc"命令,单击"确定"打开本地服务设置 3.在服务(本地)的右侧窗口找到并双击打开"DCO

使用 MyBatis 必看两篇文档导读:MyBatis 与 MyBatis-Spring

使用 MyBatis 必看两篇文档导读:MyBatis 与 MyBatis-Spring 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. MyBatis 简介 什么是 MyBatis ? MyB

iOS UIKit 框架 346 篇文档分类整理 - 预告

iOS UIKit 框架 346 篇文档分类整理 - 预告 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 当前正在进行的是 "iOS Foundation 框架 224 篇相关文档分

使用 MyBatis 必看三篇文档导读:MyBatis、MyBatis_Generator 与 MyBatis-Spring

使用 MyBatis 必看三篇文档导读:MyBatis.MyBatis_Generator 与 MyBatis-Spring 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:太阳火神的美丽人生 -  本博客专注于 敏捷开发及移动和物联设备研究:iOS.Android.Html5.Arduino.pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作. 前一篇<使用

swift学习文档(笔记)_Swift

Swift是供iOS和OS X应用编程的新编程语言,基于C和Objective-C,而却没有C的一些兼容约束.Swift采用了安全的编程模式和添加现代的功能来是的编程更加简单.灵活和有趣.界面则基于广受人民群众爱戴的Cocoa和Cocoa Touch框架,展示了软件开发的新方向. 变量与常量 变量定义使用var,常量使用let,类型安全,有自动类型推导,注意赋值的=号两边必须有空格.变量和常量名是可以几乎所有字符,这些都非常像javascript.中文编程一下牛逼了. var a = 123 /

“软文”实例分析:一篇被腾讯K掉的“分析腾讯”的文档

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 照例去qq群共享里搜集有用的资料,结果发现了一篇"审核未通过"的共享文档,文档名为"新浪内部对腾讯公司的深度解析.pdf".下载不了,找到共享人索取了这篇文档,急匆匆的看了下文档内容. (图1 内容概要) 重点看了下人才和管理体系这两个章节,为现在正为人才招聘站效力,柳青对这个更关注一些,不过实在看不出

【MOS】中文文档列表 - Oracle Database (文档 ID 1533057.1)

中文文档列表 - Oracle Database (文档 ID 1533057.1) 类型: 状态: 上次主更新: 上次更新: ANNOUNCEMENT PUBLISHED 2017-2-23 2017-2-23     文档内容 详细信息 操作   Oracle 数据库技术支持通讯   安装/升级/降级/迁移相关     日常管理相关   性能相关     集群及存储相关   高可用相关   TimesTen 内存数据库 联系人 参考 适用于: Oracle Database - Enterp

让你的WPS office文档美丽动人

文档有就像我们人类一样也需要梳妆打扮.一篇好的文档,不但要内容精彩.感人,同时也要具有华丽的外表,才能算是完美.因为我们打开文档时,首先映入我们眼帘的是文档的页面布局,其实才是文档的内容,所以,如果文档的页面设置合理,那么在一定程度上也能为文档锦上添花,使之更加"美丽动人". 那究竟怎样才能让我们的文档"美丽动人"呢?除去格式设置及文档背景外,页眉的设置也是一个也是相当重要的,通过页眉我们可以完成一些其它设置所无法完成的操作.比如说我们需要制作一个文档,而要求在页面

Word文档使用技巧

1.快速给文字加下划线 如果在Word文档中,有一段带有空格键的文本,而现在只想给该段文本中的文字加上下划线,并且忽略其中的空格.此时,请选中该段文本,然后按下"Ctrl+Shift+W"键就搞定了. 2.用特殊符号快速绘制分隔线 在用Word编辑文档时,时常会用到一些直线或是虚线作为文档的横向分隔线,常用的绘制方法是插入剪贴画中的水平线来实现,但这种方法太烦琐.其实在 Word中可以利用一些特殊符号加回车键的办法来快速绘制常用的横向分隔线.连续输入3个以上的"*"