Django之F查询和Q查询,事务及ORM部分补充

一、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数据库对于事务则是部分支持)

四个特征:

  1. 原子性:事务包含的所有操作要么全部成功,要么全部失败回滚;成功必须要完全应用到数据库,失败则不能对数据库产生影响;
  2. 一致性:事务执行前和执行后必须处于一致性状态,
  3. 隔离性:当多个用户并发访问数据库时,数据库为每一个用户开启的事务,不被其他事务的操作所干扰,多个并发事务之间要相互隔离;
  4. 持久性:一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便在数据库系统遇到故障的情况下也不会丢失事物的操作。
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字段对应的注释
原文地址:https://www.cnblogs.com/wangyisen/p/11017089.html