###############    一对一跨表查询    ################

  1. import os
  2. if __name__ == '__main__':
  3. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ORM.settings")
  4. import django
  5. django.setup()
  6. from app01 import models
  7.  
  8. # 一对一查询记录:author和authordetile是一对一的关系
  9. # 正向查询(按字段 authorDetail)
  10. # 反向查询(按表名 author):因为是一对一的关系了,就不用_set了。
  11.  
  12. # 正向查询:查询egon的手机号
  13. # 基于对象的
  14. egon_obj = models.Author.objects.filter(name="egon").first()
  15. print(egon_obj.authorDetail.telephone)
  16. # 反向查询:手机号为13245的作者的姓名
  17. deital_obj = models.AuthorDetail.objects.filter(telephone="").first()
  18. print(deital_obj.author.name)

 ###############    一对多的跨表查询    ################

  1. import os
  2. if __name__ == '__main__':
  3. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ORM.settings")
  4. import django
  5. django.setup()
  6. from app01 import models
  7.  
  8. # 外键的跨表查询
  9. # 正向查找,从多的一边查找一的一边,这是查询书籍id为1的出版社的名字
  10. # 基于对象:
  11. book1 = models.Book.objects.first()
  12. publiseh1 = book1.publish.name
  13. print(publiseh1) # tenlen
  14. # 基于下划线的:
  15. book2 = models.Book.objects.filter(nid=1).values("publish__name")
  16. print(book2) # <QuerySet [{'publish__name': 'tenlen'}]>
  17.  
  18. # 反向查找
  19. # 基于对象
  20. publisher_obj = models.Publish.objects.get(nid=1) # get返回一个对象
  21. book3=publisher_obj.book_set.all()
  22. # 如果在外键中设置了related_name = books
  23. # book3 = publisher_obj.books.all()
  24. print(book3)
  25. # 基于下划线的
  26. book4 = models.Publish.objects.filter(nid=1).values('book__title') # <QuerySet [<Book: 红楼梦>]>
  27. # 如果在外键中设置了 related_name = books
  28. # book4 = models.Publish.objects.filter(id=1).values("books__title") # <QuerySet [{'book__title': '红楼梦'}]>
  29. print(book4)

 ###############    一对多添加记录    ################

  1. import os
  2. if __name__ == '__main__':
  3. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ORM.settings")
  4. import django
  5. django.setup()
  6. from app01 import models
  7.  
  8. # 一对多的添加
  9. # 方式一:如果是这样直接指定publish_id字段去添加值,前提是你的主表里面必须有数据
  10. # 主表:没有被关联的(因为book表是要依赖于publish这个表的)也就是publish表
  11. # 子表:关联的表
  12. models.Book.objects.create(title="追风筝的人", publishDdata="2015-5-8", price="", publish_id=1)
  13. # 方式二:推荐
  14. pub_obj = models.Publish.objects.filter(name="人民出版社")[0]
  15. print(pub_obj)
  16. models.Book.objects.create(title="简爱", publishDdata="2000-6-6", price="", publish=pub_obj)
  17.  
  18. # 方式三:save
  19. pubObj = models.Publish.objects.get(name="人民出版社") # 只有一个的时候用get,拿到的直接就是一个对象
  20. bookObj = models.Book(title="真正的勇士", publishDdata="2015-9-9", price="", publish=pubObj)
  21. bookObj.save()

 ###############    一对多修改记录    ################

  1. if __name__ == "__main__":
  2. import os,django
  3. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_django.settings")
  4. django.setup()
  5. from app01 import models
  6.  
  7. # 一对多的修改,
  8. # 前端传入id,new_book_title,new_publisher_id
  9. # edit_id=1
  10. # new_book_title='水浒传'
  11. # new_publisher_id=1
  12. # edit_book_obj = models.Book.objects.get(id=edit_id)
  13. # edit_book_obj.title = new_book_title
  14. # edit_book_obj.publisher_id = new_publisher_id
  15. # edit_book_obj.save() # 保存

 ###############    多对多跨表查询    ################

  1. import os
  2. if __name__ == '__main__':
  3. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ORM.settings")
  4. import django
  5. django.setup()
  6. from app01 import models
  7.  
  8. # 多对多查询记录:
  9. # 正向查询(按字段authorlist)
  10. # 反向查询(按表名book_set)
  11.  
  12. # 正向查询:查询追风筝的人的这本书的所有的作者的姓名和年龄
  13. # 基于对象的
  14. book_obj = models.Book.objects.filter(title="红楼梦")[0]
  15. print(book_obj.authors.all().values("name", "age")) # 这本书关联的所有作者对象的集合
  16.  
  17. # 反向查询:查询作者是haiyan的这个人出了哪几本书的信息
  18. # 基于对象的
  19. haiyan_obj = models.Author.objects.filter(name="egon")[0]
  20. print(haiyan_obj)
  21. print("bookinfo====", haiyan_obj.book_set.all().first().title) # 与该作者关联的所有书对象的集合
  22. # 基于下划线的
  23. ret = models.Author.objects.filter(name="egon").values("book__title")
  24. print(ret)

 ###############    多对多跨表添加数据    ################

  1. import os
  2. if __name__ == '__main__':
  3. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ORM.settings")
  4. import django
  5. django.setup()
  6. from app01 import models
  7.  
  8. # 多对多操作
  9. # 作者和书籍就是多对多的,
  10.  
  11. # 通过作者创建一本书籍
  12. author_obj = models.Author.objects.first()
  13. from datetime import date
  14. author_obj.book.create(title='鬼吹灯',publisher_id=1,price=123,inventory_num=123,sales_num=123,pub_data=date(1999,1,1))
  15.  
  16. # 绑定多对多关系 添加一个
  17. book_obj = models.Book.objects.first()
  18. author_obj.book.add(book_obj)
  19.  
  20. # 绑定多对多关系 添加多个
  21. book_obj = models.Book.objects.filter(id__gt=4)
  22. author_obj.book.add(*book_obj)
  23.  
  24. # 解除绑定:remove: # 将某个特定的对象从被关联对象集合中去除。
  25. # 清除绑定:clear” # 清空被关联对象集合。
  26. author_obj.book.remove(book_obj)
  27. author_obj.book.clear()
  28. # 总结:remove和clear的区别
  29. # remove:得吧你要清除的数据筛选出来,然后移除
  30. # clear:不用查,直接就把数据都清空了。
  31.  
  32. # 外键的反向操作,
  33. # 找到id=1的出版社,
  34. # publisher_obj = models.Publisher.objects.get(id=1)
  35. # publisher_obj.books.clear() # 这个只是把书关联的出版社字段清空了,这本书还在,
  36. # 对于ForeignKey对象,clear()和remove()方法仅在null=True时存在

 ###############    多对多跨表修改数据    ################

  1. if __name__ == "__main__":
  2. import os,django
  3. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_django.settings")
  4. django.setup()
  5. from app01 import models
  6.  
  7. # 多对多的修改,
  8. edit_id=6
  9. new_author='南派三叔'
  10. new_publisher_id=1
  11. new_books=(1,2)
  12. edit_author_obj = models.Author.objects.get(id=edit_id)
  13. edit_author_obj.name = new_author
  14. edit_author_obj.book.set(new_books) # 这种表关联的方式是符合更新值的,这个要记住,new_books是书的id,可以是多个值,
  15. edit_author_obj.save()

###############    django--聚合和分组    ################

  1. if __name__ == "__main__":
  2. import os, django
  3.  
  4. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ORM.settings")
  5. django.setup()
  6. from app01 import models
  7.  
  8. from django.db.models import Avg, Sum, Max, Min, Count
  9.  
  10. # 聚合函数: aggregate
  11. # aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。
  12. # 查询所有书的数目
  13. print(models.Book.objects.all().aggregate(Count('nid'))) # 这是返回一个字典
  14. print(models.Book.objects.all().count()) # 这是返回一个数字,不是字典,
  15.  
  16. # 书籍销量总和
  17. print(models.Book.objects.all().aggregate(Sum('price'))) # 返回也是一个字典 {'price__sum': Decimal('123.00')}
  18. print(models.Book.objects.all().aggregate(Sum('price')).values()) # 取值 dict_values([Decimal('123.00')])
  19. # 最大和最小就是一样的使用方法
  20. ret=models.Book.objects.all().aggregate(price_avg=Avg('price'),price_max=Max('price'),
  21. price_min=Min('price'),price_sum=Sum('price')) # 为聚合值指定一个名称
  22. print(ret.get('price_max')) # 可以通过这种方式把值取出来,
  23.  
  24. # 单表查询分组
  25. # 我们在这里先复习一下SQL语句的分组
  26. # 员工表 id name age salary provice dept
  27. # 我们使用原生SQL语句,按照部分分组求平均工资:
  28. # select dept,AVG(salary) from employee group by dept;
  29. # ORM查询:
  30. # from django.db.models import Avg
  31. # Employee.objects.values("dept").annotate(avg=Avg("salary").values(dept, "avg")
  32. # 逻辑
  33. # 第一步就是按照部门分组,就先把部门查出来,
  34. # 第二步就是annotate,里面是聚合函数,
  35. # 第三步就是聚合之后平均值就是一个字段,就可以拿出来了,展示字段
  36.  
  37. # 连表查询的分组:
  38. # 员工表 id name age salary provice dept_id
  39. # 部门表 id name
  40. # SQL查询:
  41. # select dept.name,AVG(salary) from employee
  42. # inner join dept on (employee.dept_id=dept.id)
  43. # group by dept_id;
  44. # ORM查询:
  45. # from django.db.models import Avg
  46. # models.Dept.objects.annotate(avg=Avg("employee__salary")).values("name", "avg")
  47.  
  48. # 更多的例子
  49. # 示例1:统计每一本书的作者个数
  50. ret1 = models.Book.objects.all().annotate(author_num=Count('author')) # count里面是表名,
  51. # ret1是把所有的书查询出来了,但是里面的具体的书是多了一个属性就是author_num,
  52. for book in ret1:
  53. print(book.author_num)
  54. # 对结果还可以进行过滤,
  55. ret2 = models.Book.objects.all().annotate(author_num=Count('author')).filter(author_num__gt=1)
  56.  
  57. # 示例2:统计出每个出版社买的最便宜的书的价格
  58. # 第一种方法
  59. publisher_list = models.Publish.objects.annotate(min_price=Min("book__price"))
  60. for obj in publisher_list:
  61. print(obj.min_price)
  62. # 第二种方法
  63. models.Book.objects.values("publisher__name").annotate(min_price=Min("price"))
  64. # < QuerySet[{'publisher__name': '沙河出版社', 'min_price': Decimal('9.90')},
  65. # {'publisher__name': '人民出版社', 'min_price': Decimal('19.90')}] >
  66.  
  67. # 示例3:统计不止一个作者的图书
  68. models.Book.objects.annotate(author_num=Count("author")).filter(author_num__gt=1)
  69.  
  70. # 示例4:根据一本图书作者数量的多少对查询集 QuerySet进行排序
  71. models.Book.objects.annotate(author_num=Count("author")).order_by("author_num")
  72.  
  73. # 示例5:查询各个作者出的书的总价格
  74. models.Author.objects.annotate(sum_price=Sum("book__price")).values("name", "sum_price")

###############    ORMorm多对多的三种方式    ################

  1. if __name__ == "__main__":
  2. import os, django
  3.  
  4. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_django.settings")
  5. django.setup()
  6. from app01 import models
  7.  
  8. # orm多对多的三种方式
  9.  
  10. # 多对多的方式
  11. # 1,orm自动帮我创建第三张表,书和作者之间的第三张表就是自动创建的,
  12. # 2,自己创建第三张表,利用外键分别关联作者和书,查询比较麻烦
  13. # 3,自己创建第三张表,使用orm的manyTomanyField,指定一下,
  14. # book=models.ManyToManyField(to='book',through='Author2Book',through_fields=("author","book"))
  15. # 第三种的查询方式和第一种的查询方式一样的,因为已经做了关联了,
  16.  
  17. # 我们使用第几种,
  18. # 如果第三张表没有额外的字段,就使用第一种方法,
  19. # 如果第三张表有额外的字段,这种可以使用第三种方法和第一种方法,
  20. # 比如相亲网站,一个男的可以联系多个女的,一个女的也可以联系多个男的,这就是多对多的,
  21. # 约会记录,多对多,这个表的结构,
  22. # id boy_id girl_id date 约会时间,
  23. # 注意:
  24. # 第三种方式,这种add() remove() 就没有了,
  25. # 举例:
  26. # 从作者关联的书里面移除id是1的书
  27. # 之前使用第一种方法的时候是:
  28. # models.Author.objects.get(id=1).book.remove(1)
  29. # 现在自己建第三张表,就不能使用这种方式了,
  30. # models.Author2Book.objects.get(author_id=1,book_id=1).delete()
  31.  
  32. # 使用第一种方法:查询id=1的作者关联的书,
  33. # author_obj=models.Author.objects.get(id=4)
  34. # ret=author_obj.book.all()
  35. # print(ret)
  36.  
  37. # 使用自己创建的第三张表,就不能使用这种方法了,因为里面没有book这个属性啊,
  38. # 怎么拿?
  39. # 先拿到作者为1的数据,在关联表
  40. ret = models.Author2Book.objects.filter(author_id=4).values_list('book_id')
  41. print(ret) # <QuerySet [(4,), (5,)]>
  42. ret = [i[0] for i in ret] # 看来列表推导式还是需要研究一下
  43. ret = models.Book.objects.filter(id__in=ret)
  44. print(ret)
  45. # 所以这种自己建立第三张表是比较麻烦的,

对应的表结构

  1. # 自己创建第三张表的表结构
  2. class Book(models.Model):
  3. title = models.CharField(max_length=32, verbose_name="书名")
  4.  
  5. # 自己创建第三张表,并通过ManyToManyField指定关联
  6. class Author(models.Model):
  7. name = models.CharField(max_length=32, verbose_name="作者姓名")
  8. books = models.ManyToManyField(to="Book", through="Author2Book", through_fields=("author", "book"))
  9. # through_fields接受一个2元组('field1','field2'):
  10. # 其中field1是定义ManyToManyField的模型外键的名(author),field2是关联目标模型(book)的外键名。
  11.  
  12. class Author2Book(models.Model):
  13. author = models.ForeignKey(to="Author")
  14. book = models.ForeignKey(to="Book")
  15.  
  16. class Meta:
  17. unique_together = ("author", "book")

 ###############    ORM的F和Q操作    ################

  1. import os
  2.  
  3. if __name__ == '__main__':
  4. os.environ.setdefault("DJANGO_SETTINGS_MODULE", "ORM.settings")
  5. import django
  6.  
  7. django.setup()
  8. from app01 import models
  9.  
  10. # F查询
  11. # 在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?
  12. # Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。
  13. # 1、查看评论数大于阅读数的书
  14. from django.db.models import F
  15. print(models.Book.objects.filter(commentNum__gt=F("readNum")))
  16. # 2、修改操作也可以使用F函数, 比如将id大于1的所有的书的价格涨价100元
  17. print(models.Book.objects.filter(nid__gt=1).update(price=F("price") + 100))
  18. # 3、Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。
  19. # # 查询评论数大于收藏数2倍的书籍
  20. # models.Book.objects.filter(commnetNum__lt=F('keepNum')*2)
  21.  
  22. # Q查询:
  23. # filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR 语句),你可以使用Q 对象。
  24. # Q对象,表示查询条件之间的逻辑关系,与&,或 | 非~(波浪号),
  25. # 1、查询id大于1并且评论数大于100的书
  26. from django.db.models import Q
  27. print(models.Book.objects.filter(nid__gt=1, commentNum__gt=100))
  28. print(models.Book.objects.filter(nid__gt=1).filter(commentNum__gt=100))
  29. print(models.Book.objects.filter(Q(nid__gt=1) & Q(commentNum__gt=100)))
  30. # 2、查询评论数大于100或者阅读数小于200的书
  31. print(models.Book.objects.filter(Q(commentNum__gt=100) | Q(readNum__lt=200)))
  32. # Q 对象可以使用& 和| 操作符组合起来。当一个操作符在两个Q 对象上使用时,它产生一个新的Q 对象。
  33. # 3、查询年份等于2017年或者价格大于200的书
  34. print(models.Book.objects.filter(Q(publishDdata__year=2017) | Q(price__gt=200)))
  35. # 4、查询年份不是2017年或者价格大于200的书
  36. print(models.Book.objects.filter(~Q(publishDdata__year=2017) & Q(price__gt=200)))
  37. # 查询id不等于1的书籍
  38. book4 = models.Book.objects.filter(~Q(id=1))

 ###############    ORM    ################

 ###############    ORM    ################

django框架基础-ORM跨表操作-长期维护的更多相关文章

  1. django框架基础-ORM单表操作-长期维护

    ###############    单表操作-添加数据    ################ import os if __name__ == '__main__': os.environ.set ...

  2. Django框架05 /orm单表操作

    Django框架05 /orm单表操作 目录 Django框架05 /orm单表操作 1. orm使用流程 2. orm字段 3. orm参数 4. orm单表简单增/删/改 5. orm单表查询 5 ...

  3. Django框架06 /orm多表操作

    Django框架06 /orm多表操作 目录 Django框架06 /orm多表操作 1. admin相关操作 2. 创建模型 3. 增加 4. 删除 5. 修改 6. 基于对象的跨表查询 7. 基于 ...

  4. Django视图之ORM连表操作一

    1 项目路径结构树 2 models创建类 from django.db import models class UserType(models.Model): ''' 用户类型 ''' title ...

  5. Django之ORM跨表操作

    Django之ORM表查询及添加记录 一.创建表 - 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-man ...

  6. django框架基础-ORM进阶-长期维护

    ###############    ORM进阶---contenttype    ################ 设计思路: """ 路飞有两种课,专题课和学位课, ...

  7. django框架基础-ORM基础-长期维护

    ###############    ORM介绍  ################ """ ORM简介: ORM 全拼Object-Relation Mapping. ...

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

    django之跨表查询及添加记录 一:创建表 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many); ...

  9. Django之模型---ORM 多表操作

    多表操作 创建表模型 from django.db import models # Create your models here. class Author(models.Model): nid = ...

随机推荐

  1. 干货 | 用Serverless快速在APP中构建调研问卷

    Serverless 计算将会成为云时代默认的计算范式,并取代 Serverful (传统云)计算模式,因此也就意味着服务器 -- 客户端模式的终结. ------<简化云端编程:伯克利视角下的 ...

  2. sonarqube linux安装总结,集成jenkins

    第一条建议,安装sonarqube首先看好版本号,不同版本号的安装配置可能不同,如果你想走捷径,看官网对应发布的安装使用教程.https://www.sonarqube.org/downloads/ ...

  3. Python创建命令行应用的工具 tools for command line application in python

    工具1:Docopt 地址:http://docopt.org/ 这个工具是根据模块的文档注释来确定参数的.注释分为两部分:Usage, option. \``` Usage: naval_fate ...

  4. Thread--对象锁猜想

    堆内存地址未发生变化: 对象堆内存地址没发生变化的情况下,即值是否与变仍然是同一把锁. 堆内存地址变化: 在线程尝试进入过同步代码时复制当前对象锁副本. 在复制对象锁副本之后改变对象指向不影响对象锁, ...

  5. nginx下第一次使用thinkphp5遇到的坑

    最近面试php很多都在问会不会tp5所以借机了解了一下,刚在本地搭建了个就遇到了问题. 这里总结一下: 问题1.tp5+nginx=500 internal server error 我用的是phps ...

  6. python 常用函数用法

    Assert 断言assert的语法其实有点像是fi 条件分支语句的“近亲”,assert这个关键字称为“断言”,当这个关键字后边的条件为false的时候,程序自动崩溃并抛出AssertionErro ...

  7. Java常用面试题总结

    1.多线程实现方式 2.cookie和session区别 3.数据加密 4.接口并发 5.常用的集合类 6.遍历集合方式 7.接口和抽象类 8.#和$区别 9.防止sql注入 10.springMvc ...

  8. object detection模型转换成TensorFlow Lite,在Android应用

    环境 tensorflow = 1.12.0 bazel = 0.18.1 ubuntu = 16.04 python = 3.6.2 安装 bazel (0.18.1) 如果tensorflow是1 ...

  9. Python笔记_第一篇_面向过程_第一部分_5.Python数据类型之元组类型(tuple)

    元组!在Python中元组是属于列表的一种延伸,也是一种有序集合,成为一种只读列表,即数据可以被查找,不能被修改,列表的切片操作同样适用于元组. 特点:1. 与列表非常相似. 2. 一旦初始化就不能修 ...

  10. 使用迅为itop4418开发板创建Android模拟器

    基于迅为iTOP-4418开发部在 Eclipse 中,单击“Windows”菜单,选择“Android Virtual Device Manager”启动 模拟器管理插件.然后如下图,单击“Crea ...