orm多条操作

删除和修改

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

子查询和连表查询

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

  1. 一对一查询
  2. 正向查询
  3. 关系属性写在哪个表里面,那么通过这个表的数据,去查询关联的另外一张表的数据,就叫作正向查询,反之就是反向查询
  4. #正向查询使用关联属性名称
  5. #查询一下王振这个作者的手机号
  6. author_obj = models.Author.objects.get(name='王振')
  7. author_obj.ad #找到了author_obj关联的作者详细信息表里面的对应记录
  8. 主表模型类对象(author_obj).主表的关联属性名称(ad).从表属性名(telephone)
  9. print(author_obj.ad.telephone)
  10. #反向查询
  11. 反向查询用关联它的模型类的名称小写
  12. 查询一下地址在上海的那个作者是谁
  13. 从表->主表
  14. author_detail_obj = models.AuthorDetail.objects.filter(address='上海').first() #filter过滤后的是quertset类型,用first取第一个模型类对象
  15. 从表的模型类对象.主表的模型类名称小写.主表属性名
  16. print(author_detail_obj.author.name)
  17. ##########一对多#########
  18. #正向查询
  19. #使用关联属性查询
  20. #查询一下少年阿宾是哪个出版社出版的
  21. book_obj = models.Book.objects.get(title='少年阿宾')
  22. Book类的模型类对象.关联属性.name
  23. print(book_obj.pub.name)
  24. #反向查询
  25. #模型类小写_set
  26. #查询一下伟哥出版社出版了哪些书
  27. pub_obj = models.Publish.objects.get(name='伟哥出版社')
  28. pub_obj.book_set #可能为多条记录,所以模型类名小写_set
  29. #类似于objects控制器
  30. print(pub_obj.book_set.all().values('title'))
  31. #查询结果不会自动去重
  32. ######多对多######
  33. #正向查询
  34. #使用属性来查
  35. #查询一下金陵第二步这本书谁写的
  36. book_obj = models.Book.objects.get(title='金陵第二部')
  37. Book类的模型类对象.关联属性名称.all().values('name')
  38. print(book_obj.authors.all().values('name'))
  39. #反向查询
  40. #使用模型类名小写_set
  41. 查询一下谢晨写了哪些书
  42. author_obj = models.Author.objects.get(name='谢晨')
  43. print(author_obj.book_set.all().values('title'))

查看原生sql的方式

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

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

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

聚合查询(aggregate)

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

分组查询(annotate)

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

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

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

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

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

    https://www.cnblogs.com/gaoyuechen/p/8506930.html 这两天,配置了一堆500来个节点的大型集群,被ipmi的问题困扰了一天半,到下午16:40,终于解决 ...

  2. [转帖]Linux-find命令报错: missing argument to `-exec'

    https://www.cnblogs.com/yeyuzhuanjia/p/17427143.html 报错提示:find: missing argument to `-exec' 今天写一个清理脚 ...

  3. [转帖]Redis核心技术与实战

    https://www.cnblogs.com/strick/p/14851429.html 最近在读一篇关于Redis的专栏,叫做<Redis核心技术与实战>,作者在Redis方面研究颇 ...

  4. [转贴]BLOCKED,WAITING,TIMED_WAITING有什么区别?-用生活的例子解释

    BLOCKED,WAITING,TIMED_WAITING有什么区别?-用生活的例子解释 https://www.jianshu.com/p/0976b2f23db1 https://dzone.co ...

  5. CentOS8 设置开机自动登录账户的方法

    CentOS8 设置开机自动登录账户的方法 修改/etc/gdm/custom.conf文件, 并且添加内容即可. vim /etc/gdm/custom.conf # 在配置节下添加如下内容. [d ...

  6. 基于eBPF的微服务网络安全(Cilium 1)

    基于eBPF的微服务网络安全 翻译自:Network security for microservices with eBPF 一些开源的kubernetes工具已经开始使用eBPF,这些工具大多数与 ...

  7. 使用perfdog如何测试微信小程序

    测试微信小程序和测试其他app唯一的不同点是如何在app中选中要测试的小程序 至于其他的基本操作可查看https://www.cnblogs.com/lihongtaoya/p/15140610.ht ...

  8. 解锁前端新潜能:如何使用 Rust 锈化前端工具链

    ​ 前言 近年来,Rust的受欢迎程度不断上升.首先,在操作系统领域,Rust 已成为 Linux 内核官方认可的开发语言之一,Windows 也宣布将使用 Rust 来重写内核,并重写部分驱动程序. ...

  9. 文盘Rust -- 如何把配置文件打包到二进制文件里

    ​在实际开发中,经常会遇到各种不同的配置文件.通常,程序运行的各种配置从外部读取,以增强应用配置的灵活性.java 生态中的 springboot 提供了这种设计的典范.springboot 的应用程 ...

  10. &&运算提高代码质量

    sendGiveWeb: { code: 200, success: true, data: [ { id: "1230", name: "lh" }, { i ...