7 多表操作

Posted smart1san

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了7 多表操作相关的知识,希望对你有一定的参考价值。

一、多表之间的关系

 1 一对一:
 2 1?? 必须对先被关联表添加记录(即没有外键的表)
 3 2?? 关联表中的关联字段可以直接使用被关联表时的对象
 4 创建关联表时,可直接使用外键 id 传入被关联表中未被绑定的元素
 5 
 6 一对多:
 7 1?? 必须对先被关联表添加记录(即没有外键的表)
 8 2?? 关联表中的关联字段可以直接使用被关联表时的对象
 9 3?? 过滤出被关联表的对象记得加上 first() 处理
10 4?? 让关联表 id = 被关联表 id
11 
12 多对多:
13 1?? 添加关联关系使用 book.authors.add(1,2),表示的是往中间表插入记录,没有返回值
14 book:表示的是对应的 book 某本书,而不是在创建表时的 authors 属性
15 1,2:表示的是 authors.id
16 2?? book.authors.add(*(1,2))
17 3?? add(参数1,参数2) # 参数可以直接传对象,以逗号分隔

1 解除绑定关系

remove() # 需要传参数,参数即需要解除的 id 或者对象,可以是多个,用逗号分隔;也可用解压的方式(*(参数1,参数2))

2 一次性清空绑定关系

clear()  # 不用传参数

3 先清空再设置

set()  # 底层原理是先清空,然后再使用  add() 函数来添加;参数必须是可迭代对象

 

二、多表查询的总结

技术分享图片
authordetail = AuthorDetail.objects.filter(pk=zhf.authordetail_id)
print(zhf.authordetail)

# 这种情况下会查询两次,第一次是 authordetail 这个表中查询一次;第二次是 zhf.authordetail 执行查询一次
Notice

1 正向查询与反向查询

正向查询:关联字段在 A 表中,查询表 B,按字段来查询,即 A.B.字段名

反向查询:关联字段在 A 表中,由表 B 查询 表 A,按照 表名小写_set 方式来查询
如:B.a_set.all()
B.a_set 是 Manage 对象
B.a_set.all() 是 QuerySet 对象

2 正向查询方式与反向查询方式

总结 正向查询 反向查询
one to one 按照字段 表名小写
one to many 按照字段 表名小写_set
many to many 按照字段 表名小写_set

 

 

 

 

 

三、基于双下划线的多表查询(链表查询)

Django 还提供了一种直观而高效的方式在查询(lookups)中表示关联关系,它能自动确认 SQL JOIN 联系。要做跨关系查询,就使用两个下划线来链接模型(model)间关联字段的名称,直到最终链接到你想要的model 为止。

  正向查询按字段,反向查询按表名小写用来告诉ORM引擎join哪张表

1 在使用 __ 双下划线告诉 ORM 该 JOIN 哪张表前提下的总结

总结 正向查询 反向查询
one to one 按照字段 表名小写
one to many 按照字段 表名小写
many to many 按照字段 表名小写

 

 

 

 

四、聚合函数

form django.db.models.import Avg,Count,Max,Min,Sum
# 使用 aggregate() 函数表示聚合函数

Book.objects.all.aggregate(Avg(price))  # 返回值是一个字典,可传多个参数
# 给字段重命名
Book.objects.all.aggregate(avg_price=Avg(price)) 

 

五、分组

annotate() 为调用的 QuerySet 中每一个对象都生成一个独立的统计值(统计方法用聚合函数)。

from django.db.models import Avg, Max, Sum, Min, Max, Count
book_list = models.Book.objects.all().annotate(author_num=Count("authors"))
for book in book_list:
     print(book.name)
     print(book.author_num)
book_list = models.Book.objects.all().annotate(author_num=Count("authors")).values(name,author_num)
print(book_list)

 

总结 :跨表分组查询本质就是将关联表 JOIN 成一张表,再按单表的思路进行分组查询。 

技术分享图片
1?? value 在 annotate 前,表示group by 字段;在 annotate 后,表示要 select 的字段(若不写 value,默认是以基表的主键为基准)
2?? filter 在 annotate 前,指的是 where 的东西;在 annotate 后面指的是 having 的东西
Notice

 

六、F 查询和 Q 查询

1 F 查询

  Django 提供 F() 函数。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。修改操作也可以使用F函数。

from django.db.models import F,Q
#评论数大于阅读数的所有书,返回的是 QuerySet 对象
Book.objects.all().filter(commit_num__gt=F(read_num))

# 对所有的书价格 +1
Book.objects.all().update(price=F(price)+1)

2 Q 查询

  filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 若需要执行更复杂的查询(例如 OR 语句),可以使用 Q 对象

  Q 对象可以使用 & 和 | 操作符组合起来。当一个操作符在两个 Q 对象上使用时,它产生一个新的 Q 对象。

bookList=Book.objects.filter(Q(authors__name="888")|Q(authors__name="666"))

# 等同于 SQL 语句
WHERE name ="yuan" OR name ="egon"
技术分享图片
如果出现Q 对象,它必须位于所有关键字参数的前面
bookList=Book.objects.filter(Q(publish_Date__year=9999) | Q(publish_Date__year=8888), name__icontains="Django")
Notice

 



以上是关于7 多表操作的主要内容,如果未能解决你的问题,请参考以下文章

多表查询(章节摘要)

mybatis-基于xml的多表查询

Hibernate的HQL多表查询

VSCode自定义代码片段7——CSS动画

VSCode自定义代码片段7——CSS动画

Django-5.2 模型层 多表操作