本篇笔记为Django笔记系列之十二,首发于公号【Django笔记】

本篇笔记将介绍查询中的 defer 和 only 两个函数的用法,笔记目录如下:

  1. defer
  2. only

1、defer

defer 的英语单词的意思是 延迟、推迟,我们可以通过将字段作为参数传入,可以达到在获取数据的时候指定不获取该字段数据,常用于一些 textfield 字段上。

假设我们有一个 TestModel,有一个字段名为 text_field,字段类型为 textfield,里面存了大量字符串数据.

那么如果我们在获取这个 model 数据的时候,只想要这个 model 的其他字段信息, text_field 字段的内容我们在这一次用不上,那么我们就可以通过 defer() 方法来指定不获取该字段内容。

因为对于这一类大容量数据,系统在从数据库中 fetch 数据的时候会花费大量时间,而这部分不必要的时间我们是可以避免的。

TestModel.objects.defer("text_field")

上面的语句将 text_field 这个字段名作为参数传入 defer() 函数,系统返回数据的时候将不会返回他的字段。

我们以 Blog 这个model为例对这个函数进行测试,我们获取 Blog 的数据,但是指定不获取 name 这个字段的数据:

Blog.objects.defer("name")

我们可以打印一下这条命令执行的 SQL 语句:

Blog.objects.defer("name").query.__str__()
SELECT `blog_blog`.`id`, `blog_blog`.`tagline` FROM `blog_blog`

可以看到转化的 SQL 语句没有把我们指定的 name 字段返回。

不获取外键关联的某些字段

如果我们通过 select_related 关联了外键数据,也可以指定不获取外键的某些字段,比如:

Entry.objects.select_related("blog").defer("blog__name")

这样,在获取关联的 blog 的数据的时候,就不会获取 blog 的 name 字段数据。

defer 多字段

Entry.objects.defer('headline', 'body_text')

主键字段不能defer

有一些字段我们是 defer 也不会生效的,比如 model 的主键字段 id。

Blog.objects.defer("id")

上面的操作,系统不会报错,但是也不会生效。

关联外键数据,外键数据不应该被 defer

假设我们通过 Entry 来关联获取 Blog 数据,那么,关联的外键字段 blog_id,则不应该被 defer(),否则会报错。

# 下面的写法会报错
Entry.objects.select_related("blog").defer("blog_id")

访问被 defer 的字段

假设我们在获取 Blog 数据的时候,defer 了 name 字段,那么我们还可以访问 name 字段吗?

答案是可以的,不过因为我们在第一步的时候没有获取该字段,所以访问该字段的时候,系统会再次请求一遍数据库。

blog = Blog.objects.defer("name").first()

"""
这个时候打印出 blog 的所有字段是:
blog.__dict__
{'_state': <django.db.models.base.ModelState object at 0x7fb2de420668>, 'id': 1, 'tagline': 'asd'}
""" print(blog.name) # 访问被 defer 的字段,系统会再次请求数据库 """
这个时候再次打印出 blog.__dict__ 内容是:
{'_state': <django.db.models.base.ModelState object at 0x7fb2de420668>, 'id': 1, 'tagline': 'asd', 'name': 'hunter'}
"""

2、only

与 defer() 方法的作用相反,only() 的意思是只获取指定的字段,比如:

Entry.objects.only("headline", "rating")

与之对应的 SQL 是:

SELECT `blog_entry`.`id`, `blog_entry`.`headline`, `blog_entry`.`rating` FROM `blog_entry`

同样的,如果访问没有指定的字段,系统会再次查询数据库。

如果是多个 only 连用,那么系统只有最后一个 only 的字段会生效:

Entry.objects.only("headline", "rating").only("body_text")  # 只会获取 body_text 字段数据

作用效果跟 order_by() 一样,后面的参数会覆盖前面的。

defer 和 only 连用

我们可以尝试一下 defer 和 only 的先后顺序,字段是否相同,前者的字段覆盖后者,以及后者的字段覆盖前者等情况,这里不做展开了。

因为,一般人谁会把这个两个函数一起用呢。。。。。。

以上就是本篇笔记所有内容,下一篇笔记将介绍 get_or_create,update_or_create 等方法。

本文首发于本人微信公众号:Django笔记。

原文链接:Django笔记十二之defer、only指定返回字段

如果想获取更多相关文章,可扫码关注阅读:

Django笔记十二之defer、only指定返回字段的更多相关文章

  1. python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL

    python3.4学习笔记(十二) python正则表达式的使用,使用pyspider匹配输出带.html结尾的URL实战例子:使用pyspider匹配输出带.html结尾的URL:@config(a ...

  2. 《C++游戏开发》笔记十二 战争迷雾:初步实现

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9475979 作者:七十一雾央 新浪微博:http:/ ...

  3. Go语言学习笔记十二: 范围(Range)

    Go语言学习笔记十二: 范围(Range) rang这个关键字主要用来遍历数组,切片,通道或Map.在数组和切片中返回索引值,在Map中返回key. 这个特别像python的方式.不过写法上比较怪异使 ...

  4. DirectX11笔记(十二)--Direct3D渲染8--EFFECTS

    原文:DirectX11笔记(十二)--Direct3D渲染8--EFFECTS 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010333737 ...

  5. java jvm学习笔记十二(访问控制器的栈校验机制)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们 ...

  6. (C/C++学习笔记) 十二. 指针

    十二. 指针 ● 基本概念 位系统下为4字节(8位十六进制数),在64位系统下为8字节(16位十六进制数) 进制表示的, 内存地址不占用内存空间 指针本身是一种数据类型, 它可以指向int, char ...

  7. 《深入理解Java虚拟机》读书笔记十二

    第十二章  Java内存模型与线程 1.硬件效率与一致性 由于计算机的存储设备与处理器的运算速度有几个数量级的差距,所以现代计算机系统都不得不加入一层读写速度尽可能接近处理器运算速度的高速缓存(Cac ...

  8. JavaScript权威设计--命名空间,函数,闭包(简要学习笔记十二)

    1.作为命名空间的函数 有时候我们需要声明很多变量.这样的变量会污染全局变量并且可能与别人声明的变量产生冲突. 这时.解决办法是将代码放入一个函数中,然后调用这个函数.这样全局变量就变成了 局部变量. ...

  9. MySQL学习笔记十二:数据备份与恢复

    数据备份 1.物理备份与逻辑备份 物理备份 物理备份就是将数据库的数据文件,配置文件,日志文件等复制一份到其他路径上,这种备份速度一般较快,因为只有I/O操作.进行物理备份时,一般都需要关闭mysql ...

  10. swift 笔记 (十二) —— 下标

    下标 swift同意我们为 类.结构体,枚举 定义下标,以更便捷的方式訪问一大堆属性.比方Array和Dictionary都是结构体,swift的project师已经为这两个类型提供好了下标操作的代码 ...

随机推荐

  1. linux安装等

    软碟通刻入某版本linux 推荐方法 2) 1) U盘启动 修改vmlinuz initrd=initrd.img linux dd quiet 查看U盘盘符 重启修改hd:/dev/sd** qui ...

  2. js中的call()、apply()、bind()方法

    var a= { name:"李四", age: "五岁", text: function() { return this.name+ " " ...

  3. verilog 进制的表示

    n'b 是二进制 n'h 是十六进制 n'd 是四进制 n是位数

  4. Linux下查看全部的环境变量

    在Windows下,查看环境变量的命令是:set,这个命令会输出系统当前的环境变量. ... Linux查看环境变量使用env命令显示所有的环境变量 $ env

  5. 关于uniapp的事件监听,使用uni.$once和uni.$on导致的重复监听

    最近写项目的时候遇到个问题,就是在使用uniapp的事件监听器时出现重复监听问题.一开始我是用的uni.$on去监听事件,然后出现了重复的触发监听.百度了下,官方提示单次触发的建议使用uni.$onc ...

  6. 说一说webpack的配置文件

    可能有一些友友会奇怪为什么在写webpack的配置文件的时候,我们只能用commonJS导出. 原因:在打包的时候需要运行webpack的配置文件里面的代码,而webpack在打包运行的环境在node ...

  7. Longest Common Substring(最长公共子串)

    SP1811 题目描述 A string is finite sequence of characters over a non-empty finite set Σ. In this problem ...

  8. MacOS 使用UnblockNeteaseMusic解锁网易云灰色歌曲(主要是想听杰伦)

    最近想听杰伦的音乐 但是网易云木有版权 于是在github上找到了UnblockNeteaseMusic这个项目 不多废话 直接上教程! 第一步 找到该项目的地址 并使用git克隆到本地: https ...

  9. 08.File类与IO流

    一.File 类 是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. Java 把电脑中的文件和文件夹(目录)封装为了一个 File 类. File 类是与系统无关的类,任何操 ...

  10. 10、jmeter的 Http的请求默认值

    在我们测试过程当中,有很多HTTP协议的请求 这些请求 有很多比如说网址(url)都是相同的 端口也是相同的,路径可能也是相同的 这个时候就需要用到请求默认值,后续直接用就可以  不需要再去配置 后续 ...