F与Q查询
F查询
如果我们要对两个字段的值进行比较 F可以帮助我们取到表中某个字段来当做筛选条件,Django支持F()对象之间的或与常数的加减乘除和取模的操作 例子:查询卖出数大于库存数的商品 from django.db.models import F #先要导入 res=models.Product.objects.filter(maichu__gt=F('kucun')) print(res) 例子2:将每个商品的价格提高50块 models.Product.objects.update(price=F('price')+50) 注意:如果要修改char字段咋办?不能使用上面对数据的操作,这时候需要对字符串进行拼接Concat操作,并且加上拼接值Value from django.db.models.functions import Concat form django.db.models import Value res=models.Product.objects.update(name=Concat(F('name'),Value)Concat表示进行字符串的拼接操作,参数位置决定了拼接是在头部还是尾部拼接,Value里面是要新增的拼接值
Q查询
filter()等方法中逗号隔开的条件是与的关系。如果你需要执行更复杂的查询(例如OR语句),可以是使用Q对象 示例1:查询卖出数大于100或者价格小于100块的 from django.db.models.import Q models.Product.objects.filter(Q(maichu__gt=100)|Q(price__lt=100))对条件包裹一层Q的时候,filter即可以支持交叉并的比较符示例2:查询 库存数是100并且卖出数不是0的产品 moldes.Product.objects.filter(Q(kucun=100)&~Q(maichu=0)示例3:查询产品包含新款,并且库存数大于60的 models.Product.objects.filter(Q(kucun__gt=60),name__contains='新款') 查询函数可以混合使用Q,对象和关键字参数,所有提供给查询函数的参数(关键字参数或者Q对象)都将'AND'在一起,但是如果出现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)
ORM字段补充
null 用于表示某个字段可以为空unique 如果设置unique=True则该字段在此表中必须是唯一db_index 如果db_index=True则代表为此字段设置索引add_now_add=True 创建记录的时候会把当前时间添加到数据库add_now=True 每次更新数据的时候会更新该字段models.CASCADE 删除关联数据,与之关联也删除to_field 设置要关联的表的字段to 设置要关联的表的字段on_delete 当删除关联表中的数据时,当前表与其关联的行的行为。
事务
ACID(原子性,一致性,隔离性,持久性) 事物的定义:将多个sql语句操作变成原子性操作,要么同时成功,有一个失败则里面回滚到原来的状态,保证数据的完整性和一致性 # 事务 # 买一本 跟老男孩学Linux 书 # 在数据库层面要做的事儿 # 1. 创建一条订单数据 # 2. 去产品表 将卖出数+1, 库存数-1 from django.db.models import F from django.db import transaction # 开启事务处理 try: with transaction.atomic(): # 创建一条订单数据 models.Order.objects.create(num="110110111", product_id=1, count=1) # 能执行成功 models.Product.objects.filter(id=1).update(kucun=F("kucun")-1, maichu=F("maichu")+1) except Exception as e: print(e)
only与defer
#res=models.Product.objects.values('name')res=models.Product.objects.only('name')res=models.Product.objects.defer('name')for i in res: print(i.name)#only查到QuerySet包含的对象只有name字段,如果想查找其他字段会再次走数据库,所以打印速度大幅下降#defer与only相反,除了name字段,都已经得到,如果查找name字段就会再次走数据库,打印速度大幅下降
choices
res = models.Product.objects.filter(id=1).first() print(res.gender) #得到的是选择的序号 print(res.get_gender_display()) # 获取编号对应的中文注释 # models.Product.objects.create(...gender=1)#choices = ((1,'男'),(2,'女'),(3,'其他')) gender = models.IntegerField(choices=choices,default=2)