orm多条操作

删除和修改

  • 修改
      在一对一和一对多关系时,和单表操作是一样的
一对一 一个作者对应一个信息
ad_obj = models.AuthorDetail.objects.get(id=1)
models.Author.objects.filter(id=1).update(name='xx',属性名=模型类对象)
models.Author.objects.filter(id=1).update(name='xx',ad=ad_obj)
models.Author.objects.filter(id=1).update(name='xx',字段名=id字段值)
models.Author.objects.filter(id=1).update(name='xx',ad_id=1) 一对多 一个出版社出多本书
pub_obj = models.Publish.objects.get(id=2)
models.Book.objects.filter(id=1).update(title='水浒',属性名=模型类对象)
models.Book.objects.filter(id=1).update(title='水浒',pub=pub_obj)
models.Book.objects.filter(id=2).update(title='三国',字段名=id字段值)
models.Book.objects.filter(id=2).update(title='三国',pub_id=2) 多对多修改
book_obj = models.Book.objcets.get(id=4)
#用book_obj模型类对象,然后点属性(.authors)的方式操作第三张表
book_obj.authors.set('3')#参数要是可迭代类型数据
book_obj.authors.set([3,])#更新多个记录
set执行的步骤:
1.先执行clear清空
2.再执行add添加
book_obj = models.Book.objects.get(id=1)
book_obj.authors.set([4,])
  • 删除
      一对一和一对多删除一样
delete方法
models.Author.objects.filter(id=1).delete()
models.AuthorDetail.objects.filter(id=1).delete() 多对多删除remove
book_obj = models.Book.objects.get(id=1)
author_obj = models.Author.objects.get(id=2)
下面orm语句意思为在多对多关系表中删除了书籍id为1的,作者id为2的记录
#通过Book得到的模型类对象点属性(.authors)操作第三张表
book_obj.authors.remove(2) #删除单条
book_obj.authors.remove(2,3)#删除多条
  • 清空
      多对多
#将当前书籍对应的所有作者在多对多关系表中的关系记录,全部删除
book_obj = models.Book.objects.get(id=1)
book_obj.authors.clear()

子查询和连表查询

基于对象的跨表查询(子查询)

      一对一查询
正向查询
关系属性写在哪个表里面,那么通过这个表的数据,去查询关联的另外一张表的数据,就叫作正向查询,反之就是反向查询 #正向查询使用关联属性名称
#查询一下王振这个作者的手机号
author_obj = models.Author.objects.get(name='王振')
author_obj.ad #找到了author_obj关联的作者详细信息表里面的对应记录
主表模型类对象(author_obj).主表的关联属性名称(ad).从表属性名(telephone)
print(author_obj.ad.telephone) #反向查询
反向查询用关联它的模型类的名称小写
查询一下地址在上海的那个作者是谁
从表->主表
author_detail_obj = models.AuthorDetail.objects.filter(address='上海').first() #filter过滤后的是quertset类型,用first取第一个模型类对象
从表的模型类对象.主表的模型类名称小写.主表属性名
print(author_detail_obj.author.name) ##########一对多#########
#正向查询
#使用关联属性查询
#查询一下少年阿宾是哪个出版社出版的
book_obj = models.Book.objects.get(title='少年阿宾')
Book类的模型类对象.关联属性.name
print(book_obj.pub.name) #反向查询
#模型类小写_set
#查询一下伟哥出版社出版了哪些书
pub_obj = models.Publish.objects.get(name='伟哥出版社')
pub_obj.book_set #可能为多条记录,所以模型类名小写_set
#类似于objects控制器
print(pub_obj.book_set.all().values('title'))
#查询结果不会自动去重 ######多对多######
#正向查询
#使用属性来查
#查询一下金陵第二步这本书谁写的
book_obj = models.Book.objects.get(title='金陵第二部')
Book类的模型类对象.关联属性名称.all().values('name')
print(book_obj.authors.all().values('name')) #反向查询
#使用模型类名小写_set
查询一下谢晨写了哪些书
author_obj = models.Author.objects.get(name='谢晨')
print(author_obj.book_set.all().values('title'))

查看原生sql的方式

  • 1.query 适用于大部分
  • 2.在settings配置文件中写上如下内容,就能够自动打印出我们执行orm语句对应的sql
     LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
} 
  • 3.通过django配置的连接mysql的管道来查看(pymysql)
      from app01 import models
def add_book(request):
book_obj = models.Book(title='python',price=123)
book_obj.save()
from django.db import connection #通过这种方式也能查看sql语句
print(connection.queries)
return HttpResponse('OK')

基于双下划线的跨表查询(连表操作)

      原生sql写法  哪个表在前哪个表在后没区别
select * from t2 inner join t1 on t1.t2_id = t2.id;
select * from t1 inner join t2 on t1.t2_id = t2.id;
  • 一对一
      查询一下谢思敏这个作者的家庭地址
正向操作,使用属性
ret = models.Author.objects.filter(过滤条件).values('主表属性名__从表属性名')
ret = models.Author.objects.filter(name='谢思敏').values('ad__address') #<QuerySet [{'ad__address': '美国'}]>类型 反向操作,使用表名小写
ret = models.AuthorDetail.objects.filter(主表表名小写__过滤条件).values('从表属性名')
ret = models.AuthorDetail.objects.filter(author__name='谢思敏').values('address') #<QuerySet [{'address': '美国'}]>类型
  • 一对多
      查询一下少年阿宾是哪个出版社出版的
正向操作 使用关联属性
#这类的正向操作,注意看关联的属性名在哪个表里,哪个表就是主表
ret = models.Book.objects.filter(过滤条件).values('关联属性名__从表属性名')
ret = models.Book.objects.filter(title='少年阿宾').values('pub__name')#<QuerySet [{'pub__name': '橘子成人出版社'}]> 反向操作
ret = models.Publish.objects.filter(主表类名小写__过滤条件).values('从表属性名')
ret = models.Publish.objects.filter(book__title='少年阿宾').values('name')#<QuerySet [{'name': '橘子成人出版社'}]>
  • 多对多
      查询一下金陵第二部这本书谁写的
正向操作 使用关联属性
ret = models.Book.objects.filter(title='金陵第二部').values('Book类模型关联属性__author表属性名')
ret = models.Book.objects.filter(title='金陵第二部').values('authors__name')
#<QuerySet [{'authors__name': '谢思敏'}, {'authors__name': '谢晨'}]>
反向操作 使用类名小写
ret = models.Author.objects.filter(主表类名小写__过滤条件).values('从表属性名')
ret = models.Author.objects.filter(book__title='金陵第二部').values('name')
#<QuerySet [{'name': '谢思敏'}, {'name': '谢晨'}]>

聚合查询(aggregate)

      ##########聚合查询aggregate###########
统计一下所有书籍的平均价格 max min avg count sum
需要先导入
from django.db.models import Max,Min,Avg,Count,Sum
ret = models.Book.objects.aggregate(Avg('price'))
print(ret)#普通字典类型{'price__avg': 43.925}
ret = models.Book.objects.all().aggregate(a=Avg('price'),b=Max('price'))
print(ret)#{'price__avg': 43.925, 'price__max': Decimal('88.88')} , {'a': 43.925, 'b': Decimal('88.88')}
#aggregate方法可以看为是orm语句的结束语句,结果为普通字典类型,不能继续调用queryset或者模型类对象提供的方法了,也就是aggregate必须放在最后,另外里面的聚合函数可以赋值给变量

分组查询(annotate)

      ###########分组查询###########
查询一下每个出版社出版书的平均价格
ret = models.Book.objects.values('要分组的字段名').annotate(聚合函数)
ret = models.Book.objects.values('pub_id').annotate(a=Avg('price'))#只能获取到values指定的字段和统计结果数据
ret = models.Book.objects.values('pub_id','id').annotate(a=Avg('price'))#多条件分组pub_id和id值相同的算为一组 values('pub__name')#就是通过Book类的属性名跨表操作另外一张表的name
ret = models.Book.objects.values('pub__name').annotate(a=Avg('price'))#以出版社名称分组 #推荐使用下面的因为获取到模型类对象就可以用它所有的属性数据
ret = models.Publish.objects.annotate(变量a=聚合函数Avg('要关联的另外一张表的类名小写__要操作的属性'))
ret = models.Publish.objects.annotate(a=Avg('book__price'))#返回结果是Publish的模型类对象,这个模型类对象里面包含了Publish的所有属性数据,还有annotate的统计结果数据
ret = models.Publish.objects.annotate(a=Avg('book__price')).values('name','a') 原生sql,伪代码
select publish.name,Avg(book.price) from publish inner join book on publish.id = book.pub_id group by publish.id.
select avg(price) from book group by pub_id;

F查询 主要针对本表的多个字段进行比较时使用

       ########F查询#########
from django.db.models import F
#查询一下点赞数在于评论数的书籍
models.Book.objects.filter(dianzan__gt=comment)
obj_list = models.Book.objects.all().values()
a = []
for i in obj_list:
if i.dianzan > i.comment:
a.append(i)
print(a)
#上面写法太麻烦了 F查询可以用来做本表不同字段之间的一个比较
ret = models.Book.objects.filter(dianzan__gt=F('comment'))
print(ret)
F可以用来对本表数据进行一些同一操作(四则运行都支持)
将所有的书籍上调10块钱
models.Book.objects.all().update(price=F('price')+10)

Q查询 可以进行多条件查询,查询关系可以是 或与非

      from django.db.models import F
#查询书名中包含少年两个字的并且评论数大于20的书籍
ret = models.Book.objects.filter(title__contains='少年',comment__ge=20)
#filter中逗号分隔的条件,默认是and的关系
print(ret)#<QuerySet [<Book: 少年阿宾2>]> #想进行或的关系查询需要借助到我们Q查询Q
查询书名中包含少年两个字的或者评论数大于20的书籍
ret = models.Book.objects.filter(Q(title__contains='少年')|Q(comment__gt=20)) 查询书名中包含少年两个字的或者评论数大于20的,并且点赞数大于等于80的
ret = models.Book.objects.filter(Q(title__contains='少年')|Q(comment__gt=20),dianzan__gte=80)
#注意,如果结合逗号来进行and的关系查询,那么必须将没有Q包裹的查询条件放在Q包裹的查询条件后面 下面这张方式也可以,Q查询可以多层嵌套使用
# ~取反 &and关系 |or关系
ret = models.Book.objects.filter(Q(Q(title__contains='少年')|Q(comment__gt=20)) & ~Q(dianzan__gte=80))

django学习第八天--多表操作删除和修改,子查询连表查询,双下划线跨表查询,聚合查询,分组查询,F查询,Q查询的更多相关文章

  1. Django 08 Django模型基础3(关系表的数据操作、表关联对象的访问、多表查询、聚合、分组、F、Q查询)

    Django 08 Django模型基础3(关系表的数据操作.表关联对象的访问.多表查询.聚合.分组.F.Q查询) 一.关系表的数据操作 #为了能方便学习,我们进入项目的idle中去执行我们的操作,通 ...

  2. Django框架第七篇(模型层)--多表操作:一对多/多对多增删改,跨表查询(基于对象、基于双下划线跨表查询),聚合查询,分组查询,F查询与Q查询

    一.多表操作 一对多字段的增删改(book表和publish表是一对多关系,publish_id字段) 增  create publish_id 传数字   (publish_id是数据库显示的字段名 ...

  3. Python--day69--单表查询之神奇的双下划线

    单表查询之神奇的双下划线: 单表查询之神奇的双下划线 models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值 models. ...

  4. Django 数据库查询集合(双下划线连表操作)

    Django是一款优秀的web框架,有着自己的ORM数据库模型.在项目中一直使用django数据库,写一篇文章专门记录一下数据库操作.略写django工程创建过程,详写查询过程.可以和sqlalche ...

  5. django ORM模型表的一对多、多对多关系、万能双下划线查询

    一.外键使用 在 MySQL 中,如果使用InnoDB引擎,则支持外键约束.(另一种常用的MyIsam引擎不支持外键) 定义外键的语法为fieldname=models.ForeignKey(to_c ...

  6. Django模型系统——ORM中跨表、聚合、分组、F、Q

    核心知识点: 1.明白表之间的关系 2.根据关联字段确定正反向,选择一种方式 在Django的ORM种,查询既可以通过查询的方向分为正向查询和反向查询,也可以通过不同的对象分为对象查询和Queryse ...

  7. $Django 多对多-自定义第三张表 基于双下划线的跨表查询(补充)

    自定义第三张表的好处:可以定义多个字段, 缺点:查询不方便(有方法解决) 1.第三张表设置外键,联合唯一(查询不方便) class Books(models.Model): name=models.C ...

  8. Django框架(十)—— 多表操作:一对一、一对多、多对多的增删改,基于对象/双下划线的跨表查询、聚合查询、分组查询、F查询与Q查询

    目录 多表操作:增删改,基于对象/双下划线的跨表查询.聚合查询.分组查询.F查询与Q查询 一.创建多表模型 二.一对多增删改表记录 1.一对多添加记录 2.一对多删除记录 3.一对多修改记录 三.一对 ...

  9. Django框架之第六篇(模型层)--单表查询和必知必会13条、单表查询之双下划线、Django ORM常用字段和参数、关系字段

    单表查询 补充一个知识点:在models.py建表是 create_time = models.DateField() 关键字参数: 1.auto_now:每次操作数据,都会自动刷新当前操作的时间 2 ...

  10. 12月15日内容总结——ORM执行原生SQL语句、双下划线数据查询、ORM外键字段的创建、外键字段的相关操作、ORM跨表查询、基于对象的跨表查询、基于双下划线的跨表查询、进阶查询操作

    目录 一.ORM执行SQL语句 二.神奇的双下划线查询 三.ORM外键字段的创建 复习MySQL外键关系 外键字段的创建 1.创建基础表(书籍表.出版社表.作者表.作者详情) 2.确定外键关系 3.O ...

随机推荐

  1. [转帖] 在Linux上查看活跃线程数与连接数

    https://www.cnblogs.com/codelogs/p/17178675.html   原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明. 简介# 现 ...

  2. 华为云DTSE携手“灵康宜”构造一站式智慧健康检测云平台

    本文分享自华为云社区<华为云DTSE携手"灵康宜"构造一站式智慧健康检测云平台>,作者: HuaweiCloudDeveloper. 打破传统健康监测方式桎梏--非接触 ...

  3. Mygin实现中间件Middleware

    本篇是mygin的第六篇,参照gin框架,感兴趣的可以从 Mygin第一篇 开始看,Mygin从零开始完全手写,在实现的同时,带你一窥gin框架的核心原理实现. 目的 实现中间件Middleware ...

  4. 基于OpenIM 实现聊天机器人功能

    ### 简要描述 使用 OpenIM 中的 Webhook 机制实现聊天机器人功能.发送文本消息或图片消息给聊天机器人后,机器人会返回相同的消息.开发者可以替换此逻辑,在LangChain框架上调用L ...

  5. Elasticsearch中的分页查询限制和近似去重统计

    Elasticsearch 前言 深度分页的问题 如何解决 修改默认值 使用search_after方法 scroll 滚动搜索 es中的近似聚合 总结 Elasticsearch 前言 最近工作中用 ...

  6. go中bufio使用小结

    bufio 前言 例子 bufio 源码解析 Reader对象 实例化 ReadSlice ReadString ReadLine Peek Scanner Give me more data Err ...

  7. LyScript 通过PEB结构解析堆基址

    LyScript中默认并没有提供获取进程堆基址的函数,不过却提供了获取PEB/TEB的函数,以PEB获取为例,可以调用dbg.get_peb_address(local_pid)用户传入当前进程的PI ...

  8. PE格式:新建节并插入DLL

    首先老样子,我们先来到PE节表位置处,并仿写一个.hack的节,该节大小为0x1000字节,在仿写前我们需要先来计算出.hack的虚拟偏移与实际偏移,先来查询一下当前节表结构,如下: 接着我们通过公式 ...

  9. 万字剖析OpenFeign整合Ribbon实现负载均衡的原理

    大家好,前面我已经剖析了OpenFeign的动态代理生成原理和Ribbon的运行原理,这篇文章来继续剖析SpringCloud组件原理,来看一看OpenFeign是如何基于Ribbon来实现负载均衡的 ...

  10. 股价暴跌11% 但是Intel的“王者归来”时刻不远了

    当地时间1月25日美国股市盘后,处理器大厂Intel公布了2023财年第四季(截至2023年12月30日为止)及2023财年全年的财报,虽然四季度业绩整体优于分析师的预期,但是2024年第一季的业绩指 ...