Django ORM详解:事务与F、Q函数使用

事务


#事务
from django.db import transaction
from django.db.models import F
# 装饰器用法:

@transaction.atomic
def viewfunc(request):
  # 这些代码会在一个事务中执行
    ...
# with用法
try:
    #开启事物之后只有在事物里面的代码都正确运行完成才会执行相应的操作
    with transaction.atomic():
    #创建一条数据
    models.Order.objects.create(num='1111223444',count=1,product_id=5)
    #去产品表,将卖出+1,库存-1
    models.Product.objects.filter(id=5).update(kucun=F('kucun')-1,maichu=F('maichu')+1)
except Exception as e:
    print(e)

#不开启事务,会一步步的执行代码碰到bug才停止
try:
    # 创建一条数据
    models.Order.objects.create(num='1111223455', count=1, product_id=5)
     # 去产品表,将卖出+1,库存-1
    models.Product.objects.filter(id=5).update(kucun=F('kucun') - 1, maichu=F('maichu') + 1)
except Exception as e:
    print(e)

#常见的例子:银行取款和转账,只有整个执行过程都正确才会执行操作

 1. F() ---- 专门取对象中某列值的操作

F()允许Django在未实际链接数据的情况下具有对数据库字段的值的引用。通常情况下我们在更新数据时需要先从数据库里将原数据取出后方在内存里,然后编辑某些属性,最后提交。例如

order = Order.objects.get(orderid='123456789')
order.amount += 1
order.save()

F()操作在 obj.save() 后会持续存在

如果times的值是1,那么经过n次save()之后,times的值是2

obj = models.Test.objects.get(name="cox")
obj.times = obj.times + 1
obj.save()
obj.save()
obj.save()

如果times的值是1,那么经过n次save()之后,times的值是1+n,而不是2,就是因为F()操作在 obj.save() 后会持续存在

obj = models.Test.objects.get(name="cox")
obj.times = F("times") + 1
obj.save()
obj.save()
obj.save()

F()再过滤(filter)中的使用

获取表中收入(input_price)大于支出(output_price)的数据

models.Test.objects.filter(input_price__gt=F(“output_price”))

Django支持F()对象使用加、减、乘、除、取模和幂运算等算术操作,两个操作数可以是常数或F()对象

models.Test.objects.filter(input_price__gt=F(“output_price”)*2) models.Test.objects.filter(input_price__gt=F(“output_price”)+F(“output_price”))

你还可以在F()对象中使用双下划线标记来跨越关联关系。 带有双下划线的F()对象将引入任何需要的join 操作以访问关联的对象

models.Test.objects.filter(authors__name=F(‘blog__name’))

对于date 和date/time 字段,你可以给它们加上或减去一个timedelta对象

from datetime import timedelta models.Test.objects.filter(mod_date__gt=F(‘pub_date’) + timedelta(days=3))

 2. Q() ---- 对对象的复杂查询

 Q对象(django.db.models.Q)可以对关键字参数进行封装,从而更好地应用多个查询。可以组合使用 &(and),|(or),~(not)操作符,当一个操作符是用于两个Q的对象,它产生一个新的Q对象。

from django.db.models import Q
models.Author.objects.filter(Q(name="cox") | Q(name="Tom")) # 获取在Author表中,name等于cox和name等于cox的所有数据

models.Author.objects.filter(Q(name="cox") & Q(age=12))# 获取在Author表中,name等于cox并且age等于12的所有数据

Q()传入条件查询

q1 = Q()
q1.connector = 'OR'
q1.children.append(('name', "cox"))
q1.children.append(('name', "Tom"))
q1.children.append(('name', "Jeck"))
  
models.Author.objects.filter(q1) # 在Author表中,name等于cox/Tom/Jeck的所有数据
con = Q()

q1 = Q()
q1.connector = 'OR'
q1.children.append(('name', "cox"))
q1.children.append(('name', "Tom"))
q1.children.append(('name', "Jeck"))

q2 = Q()
q2.connector = 'OR'
q2.children.append(('age', 12))

con.add(q1, 'AND')
con.add(q2, 'AND')

models.Author.objects.filter(con) # 在Author表中,name等于cox/Tom/Jeck的 并且 满足age等于12 的所有数据

Q()非

在Q()语句中,~代表非

models.Author.objects.filter(~Q(name=”cox”)) # 获取在Author表中,name不等于cox的所有数据

Q对象可以与关键字参数查询一起使用,不过一定要把Q对象放在关键字参数查询的前面。

正确写法:

Order.objects.get(
    Q(create_time=date(2016, 10, 2)) | Q(create_time=date(2016, 10, 6))
    desc__startswith='Who',)

错误写法:

Order.objects.get(
    desc__startswith='Who',
    Q(create_time=date(2016, 10, 2)) | Q(create_time=date(2016, 10, 6)))

Django Q()表达式

补充知识:Django 中 Models 的 F()和 Q()函数

1、F() —- 专门取对象中某列值的操作

F对象允许Django在未实际链接数据的情况下具有对数据库字段的值的引用。

通常情况下我们在更新数据时需要先从数据库里将原数据取出后方在内存里,然后编辑某些属性,最后提交。

all = BookInfo.objects.filter(auth="小明")
for b in all:
  price = b.price
  b.price = price + 10
  b.save
  
# 使用F对象来计算
BookInfo.objects.filter(auth="小明").update(price=F("price")+10)

2、Q() —- 对对象的复杂查询

Q对象是Django对model查询中所使用的关键字参数进行封装后的一个对象。

Q对象可以通过 &(与)、 |(或)、 ~(非)运算来组合生成不同的Q对象,便于在查询操作中灵活地运用。

from django.db.models import Q
# 并且条件:与条件查询
models.User.objects.filter(条件1,条件2,条件n..)
models.User.objects.filter(Q(username='老王') & Q(userpass='admin'))

# 或者条件:或条件
models.User.objects.fliter(Q(username='老王') | Q(username='老李'))

# 取反条件
models.User.objects.filter(~Q(username='老王'))
models.User.objects.exclude(username='老王')
from django.db.models import F,Q
    # 查询评论数大于100的所有书籍名称
    # ret=Book.objects.filter(comment_count__gt=100).values("title")
 
    # 查询评论数大于点赞数的所有书籍名称
    # ret = Book.objects.filter(comment_count__gt=F("like_count")).values("title")
    # print(ret)
    # < QuerySet[{'title': 'linux'}, {'title': 'go'}] >
 
    # 查询评论数大于2倍点赞数的所有书籍名称
    # ret = Book.objects.filter(comment_count__gt=F("like_count")*2).values("title")
    # SELECT `app01_book`.`title` FROM `app01_book`
    # WHERE `app01_book`.`comment_count` > (`app01_book`.`like_count` * 2)
    # LIMIT 21;
    # print(ret) # <QuerySet []>
 
    # 给每本书籍的价格提升100
    # Book.objects.all().update(price=100+F("price"))
 
    # 查询价格大于200或者评论数并且1000 的书籍
    # ret=Book.objects.filter(price__gt=200,comment_count__gt=1000)
    # SELECT `app01_book`.`nid`, `app01_book`.`title`, `app01_book`.`price`, `app01_book`.`pub_date`,
    # `app01_book`.`comment_count`, `app01_book`.`like_count`, `app01_book`.`publish_id`
    # FROM `app01_book`
    # WHERE(`app01_book`.`comment_count` > 1000 AND `app01_book`. `price` > 200)
    # LIMIT 21;
    # print(ret)
    # < QuerySet[ < Book: linux >, < Book: javaaaaa >] >
 
    # 查询价格大于200或者评论数不大于1000 的书籍
    # 与&    或|   非~
    # ret=Book.objects.filter(Q(price__gt=200)|~Q(comment_count__gt=1000))
    # SELECT `app01_book`.`nid`, `app01_book`.`title`, `app01_book`.`price`, `app01_book`.`pub_date`,
    # `app01_book`.`comment_count`, `app01_book`.`like_count`, `app01_book`.`publish_id`
    # FROM `app01_book`
    # WHERE(`app01_book`. `price` > 200 OR NOT(`app01_book`. `comment_count` > 1000))
    # LIMIT 21;
    # print(ret)
    # < QuerySet[ < Book: linux >, < Book: javaaaaa >, < Book: go >, < Book: go >] >
 
    ret=Book.objects.filter(Q(Q(price__gt=200)|~Q(comment_count__gt=1000))&Q(like_count__gt=100))
    # 相当于
    # ret=Book.objects.filter(Q(Q(price__gt=200)|~Q(comment_count__gt=1000)),Q(like_count__gt=100))
    # SELECT `app01_book`.`nid`, `app01_book`.`title`, `app01_book`.`price`, `app01_book`.`pub_date`,
    # `app01_book`.`comment_count`, `app01_book`.`like_count`, `app01_book`.`publish_id`
    # FROM `app01_book`
    # WHERE((`app01_book`.`price` > 200 OR NOT (`app01_book`.`comment_count` > 1000))
    # AND `app01_book`.`like_count` > 100)
    # LIMIT 21;
    print(ret)
    # < QuerySet[ < Book: javaaaaa >, < Book: go >] >
    return HttpResponse("查询成功")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/908586.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【网络面试篇】HTTP(2)(笔记)——http、https、http1.1、http2.0

目录 一、相关面试题 1. HTTP 与 HTTPS 有哪些区别&#xff1f; 2. HTTPS 的工作原理&#xff1f;&#xff08;https 是怎么建立连接的&#xff09; &#xff08;1&#xff09;ClientHello &#xff08;2&#xff09;SeverHello &#xff08;3&#xff09;客户端回应 &a…

【VScode】中文版ChatGPT编程工具-CodeMoss!教程+示例+快捷键

文章目录 1. 多模型选择2. 编辑快捷键3. 历史记录收藏 CodeMoss使用教程1. 安装CodeMoss插件2. 配置AI模型3. 使用快捷键4. 进行代码优化与解释5. 收藏历史记录 总结与展望 在当今快速发展的编程世界中&#xff0c;开发者们面临着越来越多的挑战。如何提高编程效率&#xff0c;…

JqGird 动态生成列使用

使用场景&#xff1a; 在工作用需要自定义动态生成列&#xff0c;通过选择下拉框&#xff0c;加载列&#xff0c;通过查询加载列对应的数据信息 当选择文件源任务显示三列 当选择数据源任务显示两列 处理方式&#xff1a; 1. 首先在刚进入界面时初始化控件 $("#pageGri…

STM32Fxx读写eeprom(AT24C16)

一.I2C 协议简介 I2C 通讯协议 (Inter &#xff0d; Integrated Circuit) 是由 Phiilps 公司开发的&#xff0c;由于它引脚少&#xff0c;硬件实现简单&#xff0c;可扩展性强&#xff0c;不需要 USART、CAN 等通讯协议的外部收发设备&#xff0c;现在被广泛地使用在系统内多个…

鸿蒙系统的优势 开发 环境搭建 开发小示例

HarmonyOS是面向多智能终端、全场景的分布式操作系统,为消费者提供跨终端的无缝体验.华为开发者联盟从HarmonyOS应用设计、开发、测试、推广变现等环节全方位助力开发者。 开发者可以通过以下步骤学习鸿蒙系统的开发&#xff1a; 基础理论学习&#xff1a; 了解鸿蒙系统概述&a…

「C/C++」C/C++的区别

✨博客主页何曾参静谧的博客&#x1f4cc;文章专栏「C/C」C/C程序设计&#x1f4da;全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…

Windows部署rabbitmq

本次安装环境&#xff1a; 系统&#xff1a;Windows 11 软件建议版本&#xff1a; erlang OPT 26.0.2rabbitmq 3.12.4 一、下载 1.1 下载erlang 官网下载地址&#xff1a; 1.2 下载rabbitmq 官网下载地址&#xff1a; 建议使用解压版&#xff0c;安装版可能会在安装软件…

el-table 滚动条重置 手动控制滚动条

最近在使用 el-table 的时候&#xff0c;出现一个问题&#xff1a; 表头过长的时候&#xff0c;会有左右滑动的操作&#xff0c;当我们把表格拉到最右侧&#xff0c;这个时候重新请求数据的话&#xff0c;表格位置还是在最右侧&#xff0c;不会恢复原位。 那我们想恢复原位&a…

推荐FileLink数据跨网摆渡系统 — 安全、高效的数据传输解决方案

在数字化转型的浪潮中&#xff0c;企业对于数据传输的需求日益增加&#xff0c;特别是在不同网络环境之间的文件共享和传输。为了满足这一需求&#xff0c;FileLink数据跨网摆渡系统应运而生&#xff0c;为企业提供了一种安全、高效的数据传输解决方案。 安全第一&#xff0c;保…

STl学习-迭代器

1.迭代器种类 这五种迭代器的声明如下&#xff1a; truct output_iterator_tag {};//输出迭代器 truct input_iterator_tag{ };//输入迭代器 truct forward iterator tag : public input iterator tag {};//向前迭代器 truct bidirectional iterator tag :public forward iter…

自适应对话式团队构建,提升语言模型代理的复杂任务解决能力

人工智能咨询培训老师叶梓 转载标明出处 如何有效利用多个大模型&#xff08;LLM&#xff09;代理解决复杂任务一直是一个研究热点。由美国南加州大学、宾夕法尼亚州立大学、华盛顿大学、早稻田大学和谷歌DeepMind的研究人员联合提出了一种新的解决方案——自适应团队构建&…

临街矩阵乘以自己转置的含义

总结: 临街矩阵* 邻接矩阵转置的(i,j) 位置表示有多少种线路从元素A跳转一条边最终落到元素j的路线. 这个也叫1_degree.

JavaEE-多线程初阶(3)

目录 1.线程的状态 1.1 NEW、RUNNABLE、TERMINATED 1.2 TIMED_WAITING 1.3 WAITING 1.4 BLOCKED 2.多线程带来的风险-线程安全&#xff08;重点&#xff09; 2.1 观察线程不安全的现象 2.2 分析产生该现象的原因 2.3 产生线程安全问题的原因 2.3.1 抢占式执行&#x…

江协科技STM32学习- P35 硬件I2C读写MPU6050

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…

学习虚幻C++开发日志——定时器

官方文档&#xff1a;虚幻引擎中的Gameplay定时器 | 虚幻引擎 5.5 文档 | Epic Developer Community | Epic Developer Community 定时器 安排在经过一定延迟或一段时间结束后要执行的操作。例如&#xff0c;您可能希望玩家在获取某个能力提升道具后变得无懈可击&#xff0c;…

【简道云 -注册/登录安全分析报告】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…

【表格解决问题】EXCEL行数过多,WPS如何按逐行分别打印多个纸张中

1 问题描述 如图&#xff1a;我的表格行数太多了。打印在一张纸上有点不太好看 2 解决方式 Step01&#xff1a;先选中你需要打印的部分&#xff0c;找到【页面】->【打印区域】->【设置打印区域】 Step02&#xff1a;先选中一行&#xff0c;找到【插入分页符】 Step0…

提高交换网络可靠性之链路聚合

转载请注明出处 该实验为链路聚合的配置实验。 1.改名&#xff0c;分别将交换机1和交换机2改名为S1&#xff0c;S2&#xff0c;然后查看S1&#xff0c;S2的STP信息。以交换机1为例&#x1f447;。 2.交换机S1&#xff0c;S2上创建聚合端口&#xff0c;将端口加入聚合端口。以S…

SpringMVC笔记 一万字

此笔记来自于B站尚硅谷 文章目录 一、SpringMVC 简介1、什么是MVC2、什么是SpringMVC3、SpringMVC的特点 二、HelloWorld1、开发环境2、创建maven工程a>添加web模块b>打包方式&#xff1a;warc>引入依赖 3、配置web.xmla>默认配置方式b>扩展配置方式 4、创建请求…

【Hive sql面试题】找出连续活跃3天及以上的用户

表数据如下&#xff1a; 要求&#xff1a;求出连续活跃三天及以上的用户 建表语句和插入数据如下&#xff1a; create table t_useractive(uid string,dt string );insert into t_useractive values(A,2023-10-01 10:10:20),(A,2023-10-02 10:10:20),(A,2023-10-03 10:16…