分组查询、F查询和Q查询

分组查询

统计每个出版社出版的书籍的平均价格

第一种方式

1
2
obj = models.Book.objects.values('publishs_id').annotate(a=Avg('price'))
## select avg (price) from app01_ book GROUP BY publishs_ id;

第二种方式

1
2
obj = models.Publish.objects.annotate(a=Avg('book__price'))
return HttpResponse(obj.values('a'))

F查询

F查询一般用于单表两个字段比较

示例表

1
2
3
4
5
6
7
8
9
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField( max_length=32)
good = models.IntegerField(default=1)#点赞
comment = models.IntegerField(default=1)#评论
publishDate=models.DateField()
price=models.DecimalField(max_digits=5,decimal_places=2) #decimal(16,2)
publishs=models.ForeignKey(to="Publish")
authors=models.ManyToManyField(to='Author',)
1
2
3
4
5
6
##查询点赞数大于评论数的数据
obj = models.Book.objects.filter(good__gt=F('comment'))
## 支持四则运算
obj = models.Book.objects.filter(good__gt=F('comment')+2)
## 当前表中字段自增(书籍表中的价格增加20元)
obj = models.Book.objects.all().update(price = F('price')+20)

Q查询

一般用于OR关系(filter语句中时and关系)

1
2
3
#查询评论数或点赞数大于40的书籍
obj = models.Book.objects.filter(Q(good__gt=40)|Q(comment__gt=40))
#Q 对象可以使用&(与) 、|(或)、~(非) 操作符组合起来。当一个操作符在两个Q 对象上使用时,它产生一个新的Q 对象。

你可以组合&| 操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询:

1
2
bookList=Book.objects.filter(Q(authors__name="yuan") & ~Q(publishDate__year=2017)).values_list("title")
bookList=Book.objects.filter(Q(Q(authors__name="yuan") & ~Q(publishDate__year=2017))&Q(id__gt=6)).values_list("title") #可以进行Q嵌套,多层Q嵌套等,其实工作中比较常用

查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。例如:

1
2
3
bookList=Book.objects.filter(Q(publishDate__year=2016) | Q(publishDate__year=2017),
title__icontains="python" #也是and的关系,但是Q必须写在前面
)