阅读目录

  • 一、F查询

  • 二、 Q查询

  • 三、事务

  • 四、补充的一些常用的操作

摘要:

  • F查询
  • Q查询
  • 事务

一、F查询

  • 在上面所有的例子中,我们构造的过滤器都只是将字段值与某个我们自己设定的常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?
    Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。 示例:
    建表:
--------------------------------------------------------------------
注:如果你对python感兴趣,我这有个学习Python基地,里面有很多学习资料,感兴趣的+Q群:895817687
--------------------------------------------------------------------from django.db import modelsclass Goods(models.Model):name = models.CharField(max_length=32)price = models.DecimalField(max_digits=8, decimal_places=2)remain = models.BigIntegerField()sold_out = models.BigIntegerField()

插入模块

from django.db.models import F,Q

例子:查询卖出数量大于库存数的商品名称

res = models.Goods.objects.filter(sold_out__gt=F('remain')).values_list('name', 'sold_out', 'remain')
print(res)
# <QuerySet [('袜子', 600, 100), ('夹克', 20, 10)]>

F可以帮我们取到表中某个字段对应的值来当作我的筛选条件,而不是我认为自定义常量的条件了,实现了动态比较的效果

Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。基于此可以对表中的数值类型进行数学运算
例子:将每个商品的价格提高50块

res1 = models.Goods.objects.update(price=F('price')+100)

引申:如何修改char字段,比如将上面的表中商品名称全部尾部加上‘清仓’两个字,如何操作?
这里需要使用2个模块:Concat 和 Value

from django.db.models.functions import Concat
from django.db.models import Valueres = models.Goods.objects.update(name=Concat(F('name'), Value('清仓')))

Concat表示进行字符串的拼接操作,参数位置决定了拼接是在头部拼接还是尾部拼接,Value里面是要新增的拼接值

二、 Q查询

  • filter()方法汇总的逗号get的条件是与的关系,如果要执行更复杂的查询,比如or的语句,就会用到Q对象 例子:
    查询卖出数量大于100或者价格小于300的商品名
 from django.db.models import F,Qres = models.Goods.objects.filter(Q(sold_out__gt=100)|Q(price__lt=300)).values_list('name', 'sold_out', 'price')
print(res)<QuerySet [('袜子清仓', 600, Decimal('129.90')), ('寸衫清仓', 10, Decimal('229.90'))]>

对条件包裹一层Q时候,filter即可支持交叉并的比较符

# 查询库存数是小于等于20,且卖出数不是10的产品
res = models.Goods.objects.filter(Q(remain__lte=20)&~Q(sold_out=12)).values_list('name')

我们可以组合& 和| 操作符以及使用括号进行分组来编写任意复杂的Q 对象。

同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询。

# 查询产品名包含新款或者爆款,且库存大于60的产品res = models.Goods.objects.filter(Q(name__contains='新款')|Q(name__contains='爆款'), remain__gt=60).values_list('name')

查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面

  • 重点使用方法补充:
实例化Q对象:q = Q()
q.connector = 'or'    #  默认q之间的条件都是与关系,这里改成or关系
q.children.append(('name','sgt'))  # 插入第一个条件,注意这里传的是一个元祖
q.children.append(('password','123')) # 可以继续插入条件
# q对象支持直接放入filter括号内,它们之间默认是and关系,可以通过上面的q.connect = 'or'来修改成或关系
models.User.objects.filter(q)    # 这里面就是查询的条件们,它们之间默认是与关系,可以修改成or关系

三、事务

  • 定义:将多个sql语句操作变成原子性操作,要么同时成功,有一个失败在里面就回滚到原来的状态,保证数据的完整性和一致性(NoSQL数据库对事务则是部分支持)
# 事务
# 购买商品
# 产品表中修改数据:卖出数+1,库存-1
from django.db.models import F
from django.db import transaction
try :with transaction.atomic():models.Goods.objects.filter(id=1).update(remain=F('remain')-1, sold_out=F('sold_out')+1)
except Exception as e:print(e)

四、补充的一些常用的操作

  • update()与save()的区别

两者都是对数据的修改保存操作,但是save()函数是将数据列的全部数据项全部重新写一遍,而update()则是针对修改的项进行针对的更新效率高耗时少

所以以后对数据的修改保存用update()

  • 让我们通过orm对数据库操作时候,让终端显示内部查询操作sql语句:
    在Django项目的settings.py文件中,在最后复制粘贴如下代码:
LOGGING = {'version': 1,'disable_existing_loggers': False,'handlers': {'console':{'level':'DEBUG','class':'logging.StreamHandler',},},'loggers': {'django.db.backends': {'handlers': ['console'],'propagate': True,'level':'DEBUG',},}
}

配置好之后,再执行任何对数据库进行操作的语句时,会自动将Django执行的sql语句打印到pycharm终端上
补充:
除了配置外,还可以通过一点query即可查看查询语句,具体操作如下:

  • only 与 defer 拿到的是一个对象 两者是相反的
    (前提设置:设置每次操作数据库时候都会有sql语句现实在pycharm终端,上面已说明步骤) 先看看only:

    看看defer
    choice属性
    choice这个属性,用来限制用户做出选择的范围。比如说性别的选择(男或女)
class MyUser(models.Model):name = models.CharField(max_length=32)password = models.CharField(max_length=32)choices = ((1, '男'), (2, '女'), (3, '其它'))gender = models.CharField(choices=choices, default=1, max_length=5)

choice接收一个元组(保证值不可变),同理每一个选项也是由一个元组(value,display_name)构成。显而易见,display_name就是要在页面中展示的。

如何取到value和displayname?

比如说实例一个User对象user_obj,
user_obj.gender = value (通过属性取value)
user_obj.get_gender_display() = display_name (通过 get_属性_display()方法取display_name)
在模板中可以通过模板语言{{ user_obj.gender }}很简单地显示value,但不能直接调用get属性_display方法(模板毕竟是模板语言),要解决这个问题,可以用自定义过滤器来搞定:
来回顾一下如何自定义过滤器:
1,在应用名下新建一个名为templatetags文件夹
2,在该文件夹内新建一个py文件,名字随意
3,在该py文件内添加固定代码和自定义过滤器代码

from django import templateregister = template.Library()@register.filter(name='displayName')
def displayName(obj):res = obj.get_gender_displayreturn res()# 视图层:
from django.shortcuts import render, HttpResponse,reverse
# Create your views here.
from app01 import models
def index(request):obj = models.MyUser.objects.filter(pk=1).first()return render(request, 'index.html', locals())# 前端(html页面):
{% load my_file %}
{{ obj|displayName}}

bulk_create批量插入数据
当我们使用orm来一次性新增很多表记录的时候,等待结果的时间会非常的慢,如果一次性需要批量插入很多数据的时候就需要使用bulk_create来批量插入数据

import randomuser_list = ['用户[{}]'.format(i) for i in range(100)]
data = []
for j in user_list:data.append(models.MyUser(name=j, password='123', gender=str(random.choice([1, 2, 3]))))
models.MyUser.objects.bulk_create(data)
  • select_related和prefetch_related
def select_related(self, *fields)性能相关:表之间进行join连表操作,一次性获取关联的数据。总结:1. select_related主要针一对一和多对一关系进行优化。2. select_related使用SQL的JOIN语句进行优化,通过减少SQL查询的次数来进行优化、提高性能。def prefetch_related(self, *lookups)性能相关:多表连表操作时速度会慢,使用其执行多次SQL查询在Python代码中实现连表操作。总结:1. 对于多对多字段(ManyToManyField)和一对多字段,可以使用prefetch_related()来进行优化。2. prefetch_related()的优化方式是分别查询每个表,然后用Python处理他们之间的关系。

Web框架之Django_06 模型层了解(F查询、Q查询、事务、update和save、only和defer、choice属性、bulk_create)相关推荐

  1. Web框架之Django_05 模型层了解(单表查询、多表查询、聚合查询、分组查询)

    阅读目录 一.Django ORM 常用字段和参数: 二.单表查询 三.多表查询 基于双下划线的多表查询 四.聚合查询和分组查询 摘要: 单表查询 多表查询 聚合查询 分组查询 一.Django OR ...

  2. Django08-1:模型层(ORM)--聚合查询/分组查询/F与Q查询/开启事务/常用字段及参数/自定义字段/数据库查询优化

    聚合查询 单独使用时,用aggregate 1.只要是跟数据库相关的模块 基本都在django.db.models里面 如果没有应该在django.db里面 2. 聚合查询通常配合分组使用 from ...

  3. Django 模型层(models) 复杂查询详解

    Django 模型层(models) 复杂查询详解 一般Django orm 和原生sql混合使用 1.测试文件 只单独测试django中的某一个py文件 不一定是tests.py 1.配置 在任意一 ...

  4. Django聚合分组查询(F与Q查询|ORM查询优化|常见字段参数)

    文章目录 一.正反向查询进阶操作 二.聚合查询 三.分组查询 四.ORM再次添加字段 五.F与Q查询 五.ORM查询优化 六.事务操作 七.模型层常见字段 八.ORM常见字段参数 九.多对多三种创建方 ...

  5. django 中的聚合和分组 F查询 Q查询 事务cookies和sessions 066

    django 中的聚合和分组 F查询 Q查询 事务cookies和sessions 066 1 聚合和分组 聚合:对一些数据进行整理分析 进而得到结果(mysql中的聚合函数) 1aggregate( ...

  6. Django 【第六篇】ORM跨表操作(聚合查询,分组查询,F和Q查询等)

    一:创建表 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);     一本书只应该由一个出版商出 ...

  7. Web框架之Django_04 模板层了解(过滤器、标签、自定义过滤器、标签、inclusion_tag、模板的继承与导入)

    阅读目录 一.模板语法: 二.过滤器:(Filters) 三.模板的继承与模板的导入 摘要: 模版层(模板语法) 模板语法 过滤器 标签 自定义过滤器.标签 inclusion_tag 模板的继承 模 ...

  8. Web框架之Django_03 路由层了解(路有层 无名分组、有名分组、反向解析、路由分发 视图层 JsonResponse,FBV、CBV、文件上传)

    阅读目录 一.路由层:(Django的路由系统) 二.伪静态网页和虚拟环境: 三.FBV与CBV.JsonResponse.文件上传 一.路由层:(Django的路由系统) URL配置(Django项 ...

  9. Django框架——模型层单表操作、模型层多表操作、模型层常用和非常用字段和参数、模型层进阶

    文章目录 1 模型层-单表操作 一 ORM简介 二 单表操作 2.1 创建表 1 创建模型 2 更多字段 3 更多参数 4 settings配置 5 增加,删除字段 2.2 添加表纪录 2.3 查询表 ...

最新文章

  1. 第二十二章 SHELL脚本-CENTOS7.5知识
  2. 教你修改Linux下高并发socket最大连接数所受的各种限制
  3. 与服务器交互的分页组件PageComponent
  4. Java - Java集合中的安全失败Fail Safe机制 (CopyOnWriteArrayList)
  5. java ftp 下载慢_Java实现ftp文件上传下载解决慢中文乱码多个文件下载等问题
  6. android 界面切换【转】
  7. 怎么绘制机械孔_机械制图中常用的图纸简化画法,相当适合初学者!
  8. macos安装盘第三方工具制作_一步一步教你为macOS创建系统安装盘
  9. C#LeetCode刷题之#766-托普利茨矩阵(Toeplitz Matrix)
  10. 《深入理解分布式事务》第三章 Spring 事务的实现原理
  11. 小米路由器wifi显示无法连接服务器,小米路由器登录地址打不开怎么办?
  12. 微信公众号下发红包 -- PHP
  13. 马哥教育N63期-第一周作业
  14. 泰森多边形的matlab实现
  15. python怎么画三维函数图像_python中如何画三维的图形?
  16. 2023新年红包,兔年HTML红包页面代码【2023新年快乐_附源码】
  17. Java基础系列33-异常
  18. Current Mirror
  19. PS中转手绘教程汇总
  20. 如何批量将Word转换成PDF?这几种方法都可以实现批量转换

热门文章

  1. 线程/协程/异步的编程模型(CPU利用率为核心)
  2. AJAX——注册新用户的重名提示
  3. Minimum Integer
  4. Ricky’s RealDan’s Ricky
  5. java io系统_java中的io系统详解
  6. Photoshop初涉---第一次系统地学习
  7. Android 数据库(SQLite)【简介、创建、使用(增删改查、事务、实战演练)、数据显示控件(ListView、Adapter、实战演练-绿豆通讯录)】
  8. Kotlin实战指南三:流程控制
  9. SwipeBackActivity 的使用
  10. 对称加密算法原理--OpenSSL演示、iOS代码运用及CCCrypt安全隐患