一、F查询
- F可以帮我们渠道表中某个字段对应的值来当作我的筛选条件,而不是我们人为自定义常量的条件了,实现了动态比较的效果
示例1:查询出卖出数大于库存数的商品
from django.db.models import F ret1=models.Product.objects.filter(maichu__gt=F('kucun')) print(ret1)
示例2:将所有商品的价格提高100块
models.Product.objects.update(price=F('price')+100)
修改char字段的方式(不能用对数值类型的操作来操作char字段)
示例:将所有商品名字后面都加上爆款
from django.db.models import F from django.db.models.functions import Concat from django.db.models import Value models.Product.objects.update(name=Concat(F('name'),Value('爆款')))
- Concat表示进行字符串的拼接操作,参数位置决定了拼接是在头部拼接还是尾部拼接
- Value里面是要新增的拼接值
二、Q查询
- filter()等方法中逗号隔开的条件是and的关系。如果你想改变条件间的关系可以使用Q对象
示例:
from django.db.models import F, Q res = models.Product.objects.filter(Q(price=188.88),Q(name='连衣裙爆款')) # and res = models.Product.objects.filter(Q(price=188.88)|Q(name='连衣裙爆款')) # or res = models.Product.objects.filter(Q(price=188.88)|~Q(name='连衣裙爆款')) # not
混合使用(需要注意的是Q对象必须放在普通过滤条件前面)
res = models.Product.objects.filter(~Q(name='连衣裙爆款'),price=188.88) # not print(res)
Q对象的补充
from django.db.models import F, Q q = Q() q.connector = 'or' # 通过这个参数可以将Q对象默认的and关系变成or q.children.append(('price',188.88)) q.children.append(('name','高跟鞋爆款')) res = models.Product.objects.filter(q) # Q对象查询默认也是and print(res)
三、 事务
定义:将多个sql语句操作变成原子性操作,要么同时成功,有一个失败则里面回滚到原来的状态,保证数据的完整性和一致性(NoSQL数据库对于事务则是部分支持)
四个特征:
- 原子性:事务包含的所有操作要么全部成功,要么全部失败回滚;成功必须要完全应用到数据库,失败则不能对数据库产生影响;
- 一致性:事务执行前和执行后必须处于一致性状态,
- 隔离性:当多个用户并发访问数据库时,数据库为每一个用户开启的事务,不被其他事务的操作所干扰,多个并发事务之间要相互隔离;
- 持久性:一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便在数据库系统遇到故障的情况下也不会丢失事物的操作。
from django.db import transaction from django.db.models import F with transaction.atomic(): # 事务开始 # 在with代码块儿写你的事务操作 models.Product.objects.filter(id=1).update(kucun=F('kucun')-1) models.Product.objects.filter(id=1).update(maichu=F('maichu')+1) # 写其他代码逻辑 print('hahah') # 事务结束
四、ORM相关知识补充
1、update()与save()的区别
- 两者都是对数据的修改保存操作,但是save()函数是将数据列的全部数据项全部重新写一遍,而update()则是针对修改的项进行针对的更新效率高耗时少
- 所以以后对数据的修改保存用update()
2、only与defer
- 拿到的是一个对象 两者是相反的
res = models.Product.objects.values('name') res = models.Product.objects.only('name') res = models.Product.objects.defer('name')
3、choices字段
class User(models.Model): name = models.CharField(max_length=32) password = MyCharField(max_length=32) choices = ((1,'重点大学'),(2,'普通本科'),(3,'专科'),(4,'其他')) education = models.IntegerField(choices=choices) # 我们用实例化出来的对象来点education这个变量可以获得数字 user_obj.education # 拿到的是数字 # 在education前面加上get、后面加上display()可以获得数字对应的注释 user_obj.get_education_display() # 固定用法 获取choice字段对应的注释