only和defer与select_related和prefetch_Related(面试重点)

这是面试常问点

only 和 defer

only

#res = models.Book.objects.all()
    #res = models.Book.objects.values('title')
    res = models.Book.objects.only('title')
    for r in res:
        print(r.title)
        #print(r.price)

我们想要查询数据的时候,会用 all ,拿到所有对象,并且所有的字段都在对象里面。

当我们想要查询某个字段的时候,会用 values 或者values_list这两兄弟。

values查询出来的是一个字典,当我们想要用 点属性的形式点出来,就不能用values了。

这时候要用only。

上面的代码中,我们打印 r.title ,循环对象打印,这里一共会查询几次数据库? 一次!

当我们查询 r.price时,查询几次?有几个对象就查询几次。

总结:only会将括号内的字段对应的值 直接封装到返回给你的对象中 点该字段 不需要再走数据库一旦你点了不是括号内的字段 就会频繁的去走数据库查询

defer

和 only相反,defer会将括号内的字段排除之外将其他字段对应的值 直接封装到返回给你的对象中 点该其他字段 不需要再走数据库一旦你点了括号内的字段 就会频繁的去走数据库查询

 res = models.Book.objects.select_related('publish')
    res1 = models.Author.objects.select_related('author_detail')
    # res = models.Book.objects.all()
    for r in res1:
        print(r.author_detail)
        print(r.author_detail.phone)
        print(r.author_detail.addr)

上面代码查询几次数据库? 一次。

总结:

 select_related 会自动帮你做连表操作 然后将连表之后的数据全部查询出来封装给对象
    
    select_related括号内只能放外键字段
        并且多对多字段不能放,因为多对多存在第三张表,他没办法通过第三个表去连表。会直接报错。
        
    如果括号内外键字段所关联的表中还有外键字段 还可以继续连表
            select_related(外键字段__外键字段__外键字段...)

相当于两张表变成了一个表,然后所有的数据都存在了对象里面。一次查询就全部拿到了。

 res = models.Book.objects.prefetch_related('publish')
    # print(res)
    for r in res:
        print(r.publish.name)

总结:

  prefetch_related  看似连表操作  其实是类似于子查询
    prefetch_related括号内只能放外键字段
        并且多对多字段不能放
        
    如果括号内外键字段所关联的表中还有外键字段 还可以继续连表
            select_related(外键字段__外键字段__外键字段...)

补一个点(不是面试的)

django中如何开启事务

导入一个模块

from django.db import transaction
with transaction.atomic():
    在这里写的orm语句属于同一个事务,不用写什么提交,回滚之类的。
缩进出来之后自动结束事务
上一篇:Go defer使用


下一篇:命令行从Android手机中导出已安装APK的方法调研