🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
### 过滤器函数 过滤器函数即数据模型类下的Model Manager里面可以被用来当做限制条件添加的函数,一般用到较多的是all, filter, exclude, get这些函数,同时因为这些函数返回的都是成为QuerySet的对象,所以这些函数可以链式叠加 <br> **PS: QuerySet都是惰性执行,即只有在需要输出打印它的时候才会被执行** ~~~ >>> q = Entry.objects.filter(headline__startswith="What") >>> q = q.filter(pub_date__lte=datetime.date.today()) >>> q = q.exclude(body_text__icontains="food") >>> print(q) ~~~ 实际上上面的例子只执行了一次,即最后的print函数处被执行了 <br> **filter函数和get函数的区别** 简单来说,filter函数是一个不明确结果个数的函数,即filter之后的queryset可以为空,可以为多个,也可以为一个对象,但是get函数则明确了得到的对象只是一条数据,如果得到0个数据则抛出Entry.DoesNotExist异常,得到多个数据则抛出MultipleObjectsReturned异常,同时因为filter返回的是一个多对象的queryset,它的行为特性就和Python的list一样,而get函数返回的只是单个对象 <br> **raw函数** 上面的写法都是利用限制条件间接来执行SQL语句的,这里还可以通过raw函数直接执行SQL语句,这样返回的就是RawQuerySet类型 过滤器查询的一些细节 <br> 一个例子 ~~~ Blog.objects.filter(entry__headline__contains='Lennon', entry__pub_date__year=2008) Blog.objects.filter(entry__headline__contains='Lennon').filter(entry__pub_date__year=2008) ~~~ 这两个的实际效果是不一样的,第一个相当于用了SQL里的AND连接符,第二个实际上的效果是用了OR连接符,但是exclude过滤器又不是这样执行的 ~~~ Blog.objects.exclude( entry__headline__contains='Lennon', entry__pub_date__year=2008, ) Blog.objects.exclude( entry=Entry.objects.filter( headline__contains='Lennon', pub_date__year=2008, ), ) ~~~ 第一个查询并不是等同于AND操作而是等同于OR操作,第二个查询才是实现exclude下的AND操作的方法 <br> **annotate函数** 给queryset中的每一个元素赋予一个聚合函数的属性,举个栗子 ~~~ >>> from django.db.models import Count >>> q = Blog.objects.annotate(Count('entry')) # The name of the first blog >>> q[0].name 'Blogasaurus' # The number of entries on the first blog >>> q[0].entry__count 42 ~~~ 相当于将Blog的queryset中的每一个数据附了一个entry__count的属性来统计每个blog有多少访问量,当然也可以自定义属性名 ~~~ >>> q = Blog.objects.annotate(number_of_entries=Count('entry')) # The number of entries on the first blog, using the name provided >>> q[0].number_of_entries 42 ~~~