关于python:Django笔记十二之deferonly指定返回字段

30次阅读

共计 2135 个字符,预计需要花费 6 分钟才能阅读完成。

本篇笔记将介绍查问中的 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 指定返回字段

如果想获取更多相干文章,可扫码关注浏览:

正文完
 0