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, Avg, Count, Max, Min
语法: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语句', '拼接参数')#返回成功条件
Comments NOTHING