Django回顾5 - 多表操作、其它字段和字段参数、中间表的三种创建方式

【1】多表操作

  • 基于对象跨表查(子查询)
    • 执行两句sql语句,没有连表操作
  • 基于双下划线的连表查
    • 一次查询,连表操作

【2】聚合查询(aggregate)

  • 聚合函数
    • Min、Max、sum、Avg、Count

aggregate是 QuerySet 的一个终止子句,用来做聚合查询

python 复制代码
Book.objects.all().aggregate(Avg('price'))

【3】分组查询(annotate)

分组查询一般和聚合查询组合使用、annotate用来分组和聚合的

  • annotate
    • filter在annotate前:表示过滤,where条件
    • values在annotate前:表示分组的字段,如果不写表示按整个表分组
    • filter在annotate后:表示 having条件
    • values在annotate后:表示取字段---》只能取分组字段和聚合函数字段

分组目的:

把有相同特征的分成一组,分成一组后一般用来:统计总条数,统计平均数,求最大值

【4】F查询

F查询:拿到某个字段在表中具体的值

示例:

python 复制代码
 from django.db.models import F
        Book.objects.filter(评论数__gt=F('收藏数'))
        -让所有图书价格 +1
        Book.objects.all().update(price=F('price')+1)

【5】Q查询

Q查询:为了组装成 与 或 非 条件

-与条件:and条件,在filter中直接写---》就是and条件

Book.objects.filter(authors__name="lqz",price=100)

-或条件:Book.objects.filter(Q(authors__name="lqz")|Q(authors__name="justin"))

-非条件:Book.objects.filter(~Q(name='红楼梦'))

-复杂逻辑:(名字为红楼梦并且价格大于100) 或者 id 大于 2

Book.objects.filter((Q(name='红楼梦') & Q(price__gt=100))|Q(nid__gt=2))

【6】其它字段和字段参数

【6.1】字段参数:ORM字段参数

  • null
    • 表示某个字段可以为空。
  • unique
    • 如果设置为unique=True 则该字段在此表中必须是唯一的
  • db_index
    • db_index=True 则代表着为此字段设置索引
  • default
    • 为该字段设置默认值。
  • DateField和DateTimeField
    • auto_now_add=True:新增会把当前时间存入
    • default=datatime.datatime.now
    • auto_now=True,每次更新数据记录的时候会更新该字段
  • verbose_name
    • 提示,该字段的作用
  • blank
    • Admin中是否允许用户输入为空
  • editable
    • Admin中是否可以编辑
  • help_text
    • Admin中该字段的提示信息
  • choices
    • Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
    • 路由写法:get_字段名_display()

【6.2】ForeignKey属性

  • to
    • 设置要关联的表
  • to_field
    • to_field 设置要关联的表的字段
  • related_name
    • 反向操作时,使用的字段名,用于代替原反向查询时的'表名_set'
  • related_query_name
    • 反向查询操作时,使用的连接前缀,用于替换表名
  • on_delete:当删除关联表中的数据时,当前表与其关联的行的行为
    • models.CASCADE
      • 删除关联数据,与之关联也删除
    • models.DO_NOTHING
      • 删除关联数据,引发错误IntegrityError
    • models.PROTECT
      • 删除关联数据,引发错误ProtectedError
    • models.SET_NULL
      • 删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
    • models.SET_DEFAULT
      • 删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
    • models.SET:删除关联数据
      • 与之关联的值设置为指定值,设置:models.SET(值)
      • 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
    • db_constraint
      • 是否在数据库中创建外键约束,默认为True
      • db_constraint=False 在数据库中不建立外键约束
      • 虽然不建立数据库外键约束---》但是orm查询,继续用
    • ManyToManyField
      • 用于表示多对多的关联关系。在数据库中通过第三张表来建立关联关系
      • to
        • 设置要关联的表,中间是有个中间表的,区别于一对多
      • related_name
        • 同ForeignKey字段
      • related_query_name
        • 同ForeignKey字段
      • through
        • 在使用ManyToManyField字段时,Django将自动生成一张表来管理多对多的关联关系
        • 但我们也可以手动创建第三张表来管理多对多关系,此时就需要通过through来指定第三张表的表名
      • through_fields
        • 设置关联的字段
      • db_table
        • 默认创建第三张表时,数据库中表的名称

【7】中间表创建的三种方式

第一种:自动创建

自动创建用不到through和through_field

python 复制代码
authors = models.ManyToManyField(to='关联的表名')

第二种:半自动创建

手动创建中间表,使用through指定

三张表都要手动创建--》3个类--》3个表模型---》

什么情况会使用手动创建?----中间表如果有多的字段,都是手动创建

authors=models.ManyToManyField(to='Author',through='booktoauthor', through_fields=('当前表--》到中间表的外键关系','剩下的写在第二个位置'))

python 复制代码
半自动:自己创建第三张表,利用 ManyToManyField 在某张表指定关联关系
优点:可以自定义字段,依旧支持基于双下划线、对象的反向查询,可扩展性高
多对多字段的方法不支持了(add,set,remove,clear)
class Book(models.Model):
     ...
     authors = models.ManyToManyField(to='Author', through='Book2Author', through_fields=('book','author'))
 
 
class Author(models.Model):
     ...
    books = models.ManyToManyField(to='Book', through='Book2Author', through_fields=('author', 'book'))
 
class Book2Author(models.Model):
     book = models.ForeignKey(to='Book')
     author = models.ForeignKey(to='Author')
     create_time = models.DateField(auto_now_add=True)
 # through 告诉 django orm 书籍表和作者表的多对多关系是通过 Book2Author 来记录的
 # through fields 告诉 django orm 记录关系时用过 Book2Author 表中的 book 字段 和 author字段 来记录的(第一个参数 book 是  关联表查 book 所依赖的字段)
 # 但是,多对多字段的 add set remove clear 四个方法就用不了了
# 1.半自动 一定要加两个额外的参数
      through='Book2Author', through_fields=('book','author')
# 2.后面字段的顺序
      由第三张表通过哪个字段查询单表 就把哪个字段放前面

第三种,纯手动创建

不使用ManyToManyField关联

python 复制代码
纯手动:手动创建第三张表,然后利用 Foreignkey 自己做两张表的关联
优点:第三张表可以新增任意字段,扩展性较高
不足:查询不方便,基于双下划线、对象的反向查询都不支持了
            class Book(models.Model):
                ...
                
            class Author(models.Models):
                ...
            
            class Book2Author(models.Model):
                book_id = models.ForeignKey(to='Book')
                author_id = models.ForeignKey(to='Author')
                create_time = models.DateField(auto_now_add=True)
                ...
相关推荐
为思念酝酿的痛1 小时前
MySQL数据类型
数据库·mysql
泡海椒2 小时前
JQuick-SQL 与关系型数据库集成:应用层读取后注册查询
数据库·sql
Carol06302 小时前
上肢及肩肘关节
java·服务器·数据库
鸽芷咕2 小时前
数据孤岛怎么拆?金仓KFS数据集成软件从原理到落地
数据库
一世繁华行2 小时前
CAPL浏览器(翻译自官方文档)
运维·服务器·数据库
得助智能-垂类大模型2 小时前
多Agent平台哪家做得好?2026年企业级多智能体平台选型指南
大数据·数据库
为思念酝酿的痛3 小时前
MySQL数据库基础
数据库·mysql
瀚高PG实验室3 小时前
数据库使用psql及jdbc进行远程连接,不定时自动断开的解决办法
数据库·postgresql·瀚高数据库
SelectDB技术团队3 小时前
从实时入库到实时可用:Apache Doris 5.0 增量计算场景与实践
数据库·人工智能·开源·agent·实时数仓·apache doris·增量计算
Wang's Blog4 小时前
Java 项目实战: 交友项目 - 发布圈子动态:数据库表和接口文档介绍
java·数据库·交友