在接下来的四五篇笔记中,我们将详细介绍模型查询方法,为我们的查询操作提供各种便利。本篇笔记将介绍惰性搜索、过滤、排除、注释等方法,目录如下:惰性搜索filterexcludeannotatealiasorder_by1、惰性搜索我们在介绍Django的增删改查时提到了惰性搜索的规则。也就是说,普通的filter语句在执行的时候,系统是不会去查询数据库的,只有当我们真正使用到里面的数据的时候,才会去查询数据库。那么下面介绍几种使用时会查询数据库的情况:迭代一个QuerySet是可迭代的,只会在第一次迭代时查询数据库:foreinEntry.objects.all():print(e.headline)slicing需要注意的是在python中使用slicing语法是不会访问数据库的,如:Entry.objects.all()[:3]但是如果使用step语法,则会访问数据库,如以下语句:条目。objects.all()[:10:2]len()当我们使用len()函数获取一个QuerySet的长度时,我们会访问数据库,如:len(Entry.objects.all())但是不推荐这种方式,因为他会加载QuerySet中的所有数据,然后计算长度。如果我们想要获得总计数,我们将使用另一个函数.count(),稍后我们将介绍它。list()操作会强制查询数据库,然后在python中将一个QuerySet转换成一个列表。entry_list=list(Entry.objects.all())一般不推荐,因为QuerySet比list可以执行更多的功能。bool()判断是否有数据:ifEntry.objects.filter(headline='hunter'):print('exists')但是在Django中一般不推荐使用,因为有一个更高效的用法,就是使用.exists()函数,后面会详细介绍。2.filter()filter这个函数前面已经介绍过了,可以给它加上过滤条件,也可以链式操作。但是链式执行的用法是合乎逻辑的。如果要使用or逻辑,可以使用Q()的用法来配合使用,前面已经简单介绍过了。3、exclude()函数与filter()函数相反,排除符合条件的数据。4.annotate()annotate是注释的意思。在Django中用来处理数据,比如一个表达式,或者通过外键引入一个新的数据字段,或者聚合一个结果(比如平均值,综合等),前面的表达式的结果会是作为新字段添加到每条返回数据中并返回。比如我们获取Blog模型时,使用Entry作为它的外键关系。我们可以获取某个Blog关联的Entry的个数,作为一个新的字段添加到Blog中,一起返回。操作如下:q=Blog。objects.annotate(number_of_entries=Count('entry'))q[0].number_of_entries5,alias()alias()的用法和annotate一样,可以创建新的数据域,但是不像annotate(),结果不会作为字段返回,而是在使用过程中用于过滤。例如,一个用法如下:q=Blog.objects.alias(number_of_entries=Count('entry')).filter(number_of_entries__gt=1)6。order_by()对于QuerySet每次返回的结果,如果Meta中有排序参数,使用方法见前面Meta的使用说明,那么数据会按照排序参数排序返回。如果Meta中没有设置该参数,如果有主键id,则按照id的顺序返回数据。当然,我们也可以使用order_by()函数来重写每次搜索的排序数据。比如我们想对pub_date的entry模型进行正序排序:entry.objects.filter(pub_date__year=2005).order_by('pub_date')可以通过在字段前加-减号来进行逆序操作name:Entry.objects.filter(pub_date__year=2005).order_by('-pub_date')多个字段排序。例如,将pub_date倒序排序,headline正序排序,则为:Entry.objects.filter(pub_date__year=2005)。order_by('-pub_date','headline')按外键字段排序。比如模型Entry需要通过外键Blog的name字段进行排序,通过外键字段+双下划线+排序字段实现:Entry.objects.order_by('blog__name')如果我们直接排序根据外键字段,即blog,在查询Entry时,Django会使用Blog,即默认的外键排序(即Blog模型的Meta中设置的ordering来排序),如果外key没有定义默认排序,会按照主键id排序。例如,如果我们的Blog模型没有在Meta中设置默认排序,那么下面的语句:Entry.objects.order_by('blog')将等价于:Entry.objects.order_by('blog_id')Ifordering=['name']设置在Blog模型的Meta中,相当于:Entry.objects.order_by('blog__name')查询表达式调用asc()或desc()方法:Entry.objects.order_by(Coalesce('summary','headline').desc())asc()和desc()有nulls_first和nulls_last来控制空值的排序方式,无论它们是放在开头还是结尾。忽略大小写排序我们可以通过小写处理字段来达到忽略大小写排序的目的:直接调用order_by()函数,不加任何参数。Entry.objects.order_by()不支持链式处理。需要注意的是,与filter()函数的链式操作不同,order_by()不支持链式操作。每加入一次order_by(),前面的排序就会被后面覆盖。entry.objects.order_by('headline').order_by('pub_date')上面的语句只会按照pub_date排序,headline的排序会被忽略。如果要验证这个功能,答案很简单,打印出上面语句转换后的SQL语句即可。这个特性会在后面的笔记中介绍。以上就是这篇笔记的全部内容,接下来会介绍reverse、distinct、values、values_list等的用法。
