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)