本篇注解将介绍defer和only这两个函数在查询中的用法。注释列表如下:deferonly1,英文单词deferdefer的意思是延迟,延迟,我们可以通过传入字段作为参数,可以在获取数据的时候指定不获取该字段数据,经常用到一些文本字段。假设我们有一个TestModel,有一个名为text_field的字段,字段类型为textfield,里面存储了大量的字符串数据。那么如果我们在获取这个模型数据的时候只想要这个模型的其他字段信息,那么text_field这个字段的内容我们这次是不需要的,所以我们可以使用defer()方法指定不获取这个字段的内容。因为对于这种大容量的数据,系统会花费大量的时间从数据库中取数据,而我们可以避免这种不必要的时间。上面的语句TestModel.objects.defer("text_field")将字段名text_field作为参数传入defer()函数,系统返回数据时不会返回其字段。下面以Blog模型为例来测试一下这个功能。我们获取Blog的数据,但是指定不获取name字段的数据:Blog.objects.defer("name")我们可以打印这条命令执行的SQL语句:Blog.objects.defer("name").query.__str__()SELECT`blog_blog`.`id`,`blog_blog`.`tagline`FROM`blog_blog`可以看到转换后的SQL语句不包含我们指定字段返回的名称。不获取外键关联的部分字段如果我们通过select_related关联外键数据,也可以指定不获取外键的部分字段,如:Entry.objects.select_related("blog").defer("blog__name")这样在获取关联博客的数据时,不会获取到博客的name字段数据。defermulti-fieldEntry.objects.defer('headline','body_text')主键字段不能defer有些字段如果我们defer是不会生效的,比如模型的主键字段id。Blog.objects.defer("id")上面的操作不会报错,但是也不会生效。关联外键数据,外键数据不应该defer假设我们通过Entry关联获取Blog数据,那么关联的外键字段blog_id不应该defer(),否则会报错。#下面的写法会报错Entry.objects.select_related("blog").defer("blog_id")访问defered字段假设我们在获取Blog数据时defer了name字段,是否还能访问name字段??答案是肯定的,但是由于第一步我们没有获取到这个字段,所以在访问这个字段的时候,系统会再次请求数据库。blog=Blog.objects.defer("name").first()"""这时候打印博客的所有字段:blog.__dict__{'_state':
