06-模型层9—多表操作之F查询与Q查询
在Book表中新增两个字段:read_num与content_num
1
由于之前已经加了数据了,想要在有数据的表中再新增字段,那么需要之前的记录设置default值
2
在Book类中新增:
class Book(models.Model):
##前面的字段略##
##新增两个字段
##加上 default=0 添加这两个字段后,之前的记录的这两个字段都默认为0
read_num = models.IntegerField(default=0)
content_num = models.IntegerField(default=0)
然后,在Terminal中运行:
python3 manage.py makemigrations
python3 manage.py migrate
就可以将上面两个字段添加到book表中。
F查询
说明
1、在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?
2、Django提供F()来做这样的比较。F()的实例可以在查询中引用字段,来比较同一个model实例中两个不同字段的值。
3、需要先引入F
from django.db.models import F
举例
1-字段间的比较
查询同一张表中评论数大于点赞数的书籍的名字~
查询content_num大于read_num的书籍的名字
ret = Book.objects.filter(content_num__gt=F('read_num')).values('title')
print(ret)
#<QuerySet [{'title': '水浒传'}, {'title': '金瓶'}, {'title': '三国群英传'}, {'title': '三国群英'}]>
2-统一修改——与update结合
将每个书籍的价格加10元
Book.objects.all().update(price=F('price')+10)
#给价格小于10元的书籍的价格增加10元
Book.objects.filter(price__lt=10).update(price=F('price')+10)
Q查询
说明
1、filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象。
2、需要先引入Q
from django.db.models import Q
举例
1
查找书名以“三国”开头或者价格等于100的书籍名称
ret = Book.objects.filter(Q(title__startswith='三国') | Q(price=100)).values('title')
print(ret)
#<QuerySet [{'title': '三国群英传'}, {'title': '三国群英'}]>
2
查找书名不以“三国”开头的书籍名称
ret = Book.objects.filter(~Q(title__startswith='三')).values('title')
print(ret)
#<QuerySet [{'title': '金瓶'}, {'title': '水浒传'}, {'title': '金瓶'}]>
3
Q查询与键值对的关系:先写Q再写键值对,而且是“且”的关系:
ret = Book.objects.filter(~Q(title__startswith='三'),title__startswith='水').values('title')
print(ret)
#<QuerySet [{'title': '水浒传'}]>