F查询与Q查询

F查询与Q查询

1、 aggregate

若想把整张表当成一个组来使用聚合函数,应该调用aggregate

# 1、先导入聚合函数
from django.db.models import Max, Min, Avg, Sum, Count
"""
小窍门:
只要是跟数据库相关的模块基本都在django.db.models里面
如果没有那么应该在django.db里
"""

# 2、查询所有作者的最大nid、最小年龄、平均年龄、年龄之和、作者个数

res = Author.objects.aggregate(
        Max("age"),
        Min("age"), 
        Avg("age"), 
        Sum("age"), 
        Count("nid")
    )

print(res)  # 调用的sql为:select avg("age"),max("nid"),... from app01_author;
{'age__max': 30, 'age__min': 10, 'age__avg': 20.0, 'age__sum': 60, 'nid__count': 3}

# 3、也可以指定key值
res = Author.objects.aggregate(
        x=Max("age"),
        y=Min("age"),
    )
print(res) 
{'x': 30, 'y': 10}

2、F查询

F查询够帮你直接获取到表中的某个字段对应的值,具体应用如下

# 修改模型Book增加阅读数与评论数字段,然后重新迁移数据库,新增好记录
class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField(auto_now_add=True)
    # 阅读数
    read_num=models.IntegerField(default=0)
    # 评论数
    comment_num=models.IntegerField(default=0)

    publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)
    authors=models.ManyToManyField(to='Author')
    def __str__(self):
        return self.name

    
from django.db.models import F
# 1、查询阅评论数大于阅读数的书籍名
res = Book.objects.filter(comment_num__gt=F("read_num"))
print(res)

# 2、将所有书的价格在原来的基础上增加50元
Book.objects.update(price=F("price")+50)

注意,针对数字运算,F可以直接与数字进行数学运算,但如果我们想拼接字符串,则需要引入Concat并配合Value一起实现,如下

# 3、将所有书籍的名称后面加爆款两个字
from django.db.models.functions import Concat
from django.db.models import Value, F

Book.objects.update(name=Concat(F('name'), Value("爆款")))
# Book.objects.update(name=F('name') + "爆款")  # 错误,所有书的名字都会被改为0

3、Q查询

对于filter()方法内逗号分隔开的多个条件,都是and关系,如果想用or或者not关系,则需要使用Q

from django.db.models import Q

Book.objects.filter(Q(nid__gte=3), Q(nid__lte=5))  # 还是and关系
Book.objects.filter(Q(nid__lte=3) | Q(nid__gte=5))  # or关系

Book.objects.filter(~Q(nid__gt=2))  # ~ 等同于在条件前加了not  代表: ! nid>2即nid<=2
Book.objects.filter(~Q(nid__gt=2) | Q(nid__gte=5))  #  代表nid<=2 or nid>=5

Q查询的高阶用法:能够以字符串作为查询字段

q = Q()
q.children.append(('nid__gt', 2))  # 条件中引用的字段为字符串类型
q.children.append(('price__lt', 50))
res = Book.objects.filter(q)  # filter内可以直接放q对象,默认还是and关系
print(res)


q = Q()
q.connector = 'or'
q.children.append(('nid__lte', 2))
q.children.append(('nid__gte', 5))
res = Book.objects.filter(q)  # 此时是or关系
print(res)

# 那什么场景下,我们查询条件中的字段是字符串类型呢?
# 比如我们制作一个搜索功能,我们需要根据用户输入搜索字段完成查询,而用户输入的都是字符串类型,此时就用到了Q的高阶用法
posted @   yedayang  阅读(51)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示