django模型层FQ查询,only,defer关键字,orm简单事务
前言:
Q查询—对对象的复杂查询
F查询–专门取对象中某列值的操作
Q查询
1.Q查询(django.db.models.Q)可以对
关键字参数进行封装,从而更好的封装
from django.db.models import Q from login.models import New #models对象 news=New.objects.filter(Q(question__startswith='What'))
2.Q对象可以用~操作符放在前面表示否定,也可允许否定与不否定形式的组合
res = models.Book.objects.filter(Q(title="西游记")|~Q(publish_id=2)) print(res)
3.Q查询可以让filter过滤实现或的条件使用|
res = models.Book.objects.filter(Q(title="西游记")|Q(publish_id=2)) print(res)
4.应用范围组合查询:
res = models.Book.objects.filter( Q(title="西游记"), Q(publish_id=2)|Q(publish_time="2019-06-13")) print(res) 等价于 select *from where title ="西游记" and(publish_id=2 orpublish_time="2019-06-13")
5.Q对象可以与关键字参数查询一起使用,不过一定要把Q对象放在关键字参数查询的前面
正确: models.Book.objects.filter( Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)), question__startswith='Who') 错误: Poll.objects.get( title="西游记", Q(publish_id=2)|Q(publish_time="2019-06-13"))
F查询:
F查询–专门取对象中
某列值的操作
F本质是是列操作:
看如下示例:
当我们要查询销量大于库存的商品时,就要使用F查询了:
销售与剩余的分别是一列:因此用F查询再好不过了
from django.db.models import F,Q
# F查询
res = models.Product.objects.filter(sell__gt=F(‘stock’))
print(res)
同样我们可以将某列的值进行增减对价格:
from django.db.models import F models.Book.objects.update(price= F("price")+10)
ORM不支持+拼接字符串,mysql中我们拼接字符串要用concat,此处同理:
# 要进行字符串的拼接需要先导入Concat和Value模块 from django.db.models.functions import Concat from django.db.models import Value models.Product.objects.update(name=Concat(F('name'), Value('爆款')))
事务
事务的四大特性:
Atomic(原子性):事务中包含的操作被看做一个逻辑单元,这个逻辑单元中的操作要么全部成 功,要么全部失败。
Consistency(一致性):事务完成时,数据必须处于一致状态,数据的完整性约束没有被破坏,事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没 有执行过一样。
Isolation(隔离性):事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性 和完整性。同时,并行事务的修改必须与其他并行事务的修改相互独立。
Durability(持久性):事务结束后,事务处理的结果必须能够得到固化。
事务的语法
在sql语句中使用事务时,我们需要用start开启事务,又要用end结束事务,这就需要我们判断事务何时开始和结束比较好。而在Django的ORM中,直接使用上下文管理即可,省事又省心。
这里直接拿上面提到过的销售表做示例,比如一件商品卖出后,销量要+1,对应的库存要-1。
from django.db import transation from django.db.models import F with transaction.atomic(): models.Product.objects.filter(id=1).update(stock=F("stock")-1) models.Product.objects.filter(id=1).update(price=F("price")+1)
only和defer
only和defer返回的是列表套对象的QuerySet对象,有点类似filter()和exclude()的类似,包含与不包含
# 输出一下用values取出来的结果(列表套字典,键为'name') test = models.Product.objects.values('name') print(test) # only取出来的是列表套对象,对象只有name属性 res = models.Product.objects.only('name') for i in res: print(i.name) # defer取出来的是列表套对象,对象除了name属性,其他属性都有 res1 = models.Product.objects.defer('name') for i in res: print(i.name)
自定义字段:
Django支持自定义字段,需要继承models.Field类
class MyCharField(models.Field): def __init__(self,max_length,*args,**kwargs): self.max_length = max_length super().__init__(max_length=max_length,*args,**kwargs) def db_type(self,connnection): return 'char(%s)'%self.max_length
字段中的choice属性:
当我们给一个表新增一个字段时,如果表中已经有数据了,那么我们可以将models.py中新增的字段名null设置默认值或者是设置为空。
gender = models.IntegerField(default=2)
允许为空:
gender= models.CharField(null=True)
choices属性使用的场景也挺多,比如性别,在数据库中我们可以存储数字,比如1代表男,2代表女,而显示给用户看时,要转变为对应的男或女
示例:
class User(models.Model): name = models.CharField(max_length=32) choice = ((1,"男"),(2,"女")) gender = models.IntegerField(choices = choices,default=2) ``` 这样数据库存的就是数字,怎么取出来如下: res = models.User.objects.filter(id = 1).first() print(res.gender) #获取编号对应的中文注释,固定写法get_字段名_display() print(res.get_gender_display()) 创建对象时任然传数字 models.User.objects.create(name='wy',gender=1)
- python3开发进阶-Django框架中的ORM的常用操作的补充(F查询和Q查询,事务)
- Django ORM相关操作|F、Q查询、事务、外键正向反向查询、聚合分组
- Cost Readonly Static关键字简单比较
- Django流程(Django虚拟环境的搭建,项目创建以及模板、视图、模型的简单介绍)
- 建立一个更高级别的查询 API:正确使用Django ORM 的方式 - 技术翻译 - 开源中国 OSChina.NET
- django 模型层多对多表创建,简单ajax,组件分页器
- Django基础-----ORM简介、数据库中数据操作及简单的一对多模型
- Django系列教程(3)-- 模型的查询
- django ORM model filter 条件过滤,及多表连接查询、反向查询,某字段的distinct
- django模型ORM笔记
- Laravel[Eloquent ORM简介、模型的建立及查询数据]
- Django模型系统——ORM表结构对应关系
- Django开发(十)---ORM模糊查询之万能双下划线
- django中模型的简单操作
- 4.Django|ORM模型层
- 【转】建立一个更高级别的查询 API:正确使用Django ORM 的方式
- 在Django的模型中执行原始SQL查询的方法
- 光脚丫学LINQ(016):创建简单对象模型和LINQ查询(C#)
- 使用ES做简单的时间条件过滤+模糊查询+精确匹配+关键字排除
- django 事务小结(ORM 事务以及raw sql,customize sql 事务处理)