• Django笔记十二之defer、only指定返回字段


    本文首发于微信公众号:Hunter后端
    原文链接:Django笔记十二之defer、only指定返回字段

    本篇笔记将介绍查询中的 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': , 'id': 1, 'tagline': 'asd'}
    """
    
    print(blog.name) # 访问被 defer 的字段,系统会再次请求数据库
    
    """
    这个时候再次打印出 blog.__dict__ 内容是:
    {'_state': , '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 等方法。

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

  • 相关阅读:
    高比例清洁能源接入下计及需求响应的配电网重构(matlab代码)
    Web3D虚拟人捏脸
    【NoSQL】NoSQL之redis配置与优化(简单操作)
    TiUP 命令概览
    深入理解Spring中的Ioc
    ImageDecoder解码GIF、ImageView显示GIF
    关于在Linux服务上安装nvm,踩坑步骤说明
    Windows 驱动开发 新手入门(四)
    网页大作业代码自取【HTML+CSS制作美味糖果网站】
    ThingsBoard教程(二八):详细讲解在tb平台下 mqtt协议下的 rpc 遥测,客户端rpc,服务的rpc的使用 ,与node-red联动
  • 原文地址:https://www.cnblogs.com/hunterxiong/p/17274387.html