ORM中的F对象与Q对象

酥酥 发布于 2021-09-18 965 次阅读


ORM中的F对象与Q对象

F对象

一个F对象代表数据库中某条记录的字段的信息作用:

  • 通常是对数据库中的字段值在不获取的情况下进行操作

  • 用于类属性(字段)之间的比较。

语法

from django. db. models import F

F(列名)

示例1:更新Book实例中所有的零售价涨10元
Bookobjects.all().update(market_price=F('market_price')+ 10)
UPDATE bookstore_book SET market_price (bookstore_book.market_price +10)
以上做法好于如下代码 books= Book.objects.all()
for book in books:
book.market_price=book.market_price+10
book.save()

F可以控制并发,后者访问量大的时候可能会读脏数据

F并不是要取,而是成为简化增删改查的工具 累增,表内比较….

Q对象

当在获取查询结果集使用复杂的逻辑或丨、逻辑非~等操作时可以借助于Q对象进行操作(and &也行,Q(条件1)&!Q(条件2)也可以)

如:想找出定价低于20元或清华大学出版社的全部书,可以写成

Book.objects.filter(Q(prIce_lt=20)&Q(pub=”清华大学出版社”)

Q对象在数据包 django. db. models中。需要先导入再使用




聚合

整表查询

不带分组的聚合查询是指导将全部数据进行集中统计查询聚合函数[需要导入]
-导入方法:from django.db.models import *
聚合函数:Sum, AvgCountMaxMin
语法:classname.objects.aggregate(结果变量名=聚合函数() )#结果变量名是自定义的
返回结果:结果变量名和值组成的字典格式为:"结果变量名":值}#字典类型

分组聚合

分组聚合是指通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值(也可以是平均值或总和),即为查询集的每一项生成聚合语法:
-QuerySet.annotate(结果变量名=聚合函数('列') )返回值:
-QuerySet

所以要先classname.objects.values(‘列1′,’列2’)得到分组QuerySet

可以Queryset.annotate(结果变量名=聚合函数(‘列’).filter(结果变量名_gt=1))来实现聚合后筛选

原生数据库操作

Django也可以支持直接用sql语句的方式通信数据库
查询:使用classname.objects.raw() 进行数据库查询操作查询
语法:My Model.objects.raw(sql语句,拼接参数)
返回值:Raw_Query_Set集合对象 【只支持基础操作,比如循环、索引】一步到位
books=mode1s.Book.objects.raw('select* from bookstore_book') 
for book in books:
       print(book)

弊端:sql注入

用户通过数据上传,将恶意的sql语句提交给服务器,从而达到攻击的效果,因为原生数据库本质需要自己字符串拼接,不合法的sql语句就由此而来

sql注入防范

错误->s 1=Book.objects.raw(‘select*from bookstore_book where id=%s’%(‘1or 1=1’) )

正确->s 2=Book.objects.raw(‘select*from bookstore_book where id=%s’, [‘1or 1=1’] )


原生到爆炸贴近pymysql的用法

完全跨过模型类操作数据库-查询/更新/删除
1.导入cursor所在的包from django.db import connection
2.用创建cursor类的构造函数创建cursor对象, 再使用cursor对象,为保证在出现异常时能释放cursor资源, 通常使用with语句进行创建操作
from django.db import connection
with connection.cursor() as cur:
cur.execute('执行SQL语句''拼接参数')#返回成功条件