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)
                ...
相关推荐
cyt涛1 小时前
MyBatis 学习总结
数据库·sql·学习·mysql·mybatis·jdbc·lombok
Rookie也要加油1 小时前
01_SQLite
数据库·sqlite
liuxin334455661 小时前
教育技术革新:SpringBoot在线教育系统开发
数据库·spring boot·后端
看山还是山,看水还是。2 小时前
MySQL 管理
数据库·笔记·mysql·adb
fishmemory7sec2 小时前
Koa2项目实战2(路由管理、项目结构优化)
数据库·mongodb·koa
momo小菜pa2 小时前
【MySQL 09】表的内外连接
数据库·mysql
Jasonakeke3 小时前
【重学 MySQL】四十九、阿里 MySQL 命名规范及 MySQL8 DDL 的原子化
数据库·mysql
程序猿小D3 小时前
第二百六十九节 JPA教程 - JPA查询OrderBy两个属性示例
java·开发语言·数据库·windows·jpa
小宇成长录3 小时前
Mysql:数据库和表增删查改基本语句
数据库·mysql·数据库备份
团儿.4 小时前
解锁MySQL高可用新境界:深入探索MHA架构的无限魅力与实战部署
数据库·mysql·架构·mysql之mha架构