1. 多对多的外键增删改查图书和作者是多对多,借助于第三张表实现的,如果想绑定图书和作者的关系,本质上就是在操作第三方表2. 如何操作第三张表问题:让你给图书添加一个作者,他俩的关系可是多对多多对多的增删该查1. 给图书id = 2 添加一个作者id = 1 book_obj =  models. Book. objects. filter ( pk= 2 ) . first( ) print ( book_obj. authors)  借助于内置方法add( ) book_obj. authors. add( 1 )   book_obj. authors. add( 2 , 3 )  也支持写对象2. 删除book_obj. authors. remove( 1 ) 3. 修改book_obj. authors. set ( [ 1 , 3 ] )   4. 清空表book_obj. authors. clear( )   总结:操作第三张表 通过外键字段点下面的方法add remove set  clear 子查询:一个SQL语句的执行结果当成另一个SQL语句的执行条件,分步操作连表查询:把多个表关联在一起拼接成一个大的虚拟表,然后按照单表查询inner joinleft  joinright joinunion
select *  from  course inner join teacher on course. id = teacher_course_id where id = 1 ; select *  from  course as  c inner join teacher as  t on course. id = teacher_course_id left join class  on  class . id = c. class_id where c. id = 1 先判断是正向还是反向查询
1. 正向外键字段在我手上,我查你就是正向查询
2. 反向外键字段在我手上,你查我就是反向查询3. 判断出来正向和反向之后有什么用正向查询按照字段查询( 外键字段) 反向查询按照表名小写或者表名小写_set
	res =  models. Book. objects. filter ( pk= 1 ) . first( ) print ( res. publish)   print ( res. publish. name) print ( res. publish. addr) book_obj =  models. Book. objects. filter ( pk= 2 ) . first( ) print ( book_obj)   print ( book_obj. authors. all ( ) )   print ( book_obj. authors. all ( ) [ 0 ] . name)   print ( book_obj. authors. all ( ) [ 0 ] . age)   author_obj =  models. Author. objects. filter ( name= 'jerry' ) . first( ) print ( author_obj. author_detail)  print ( author_obj. author_detail. phone) publish_obj =  models. Publish. objects. filter ( name= '北京出版社' ) . first( ) print ( publish_obj. book_set)   print ( publish_obj. book_set. all ( ) )   print ( publish_obj. book_set. all ( ) [ 0 ] . title)   author_obj =  models. Author. objects. filter ( name= 'tom' ) . first( ) print ( author_obj. book_set)   print ( author_obj. book_set. all ( ) )   author_detail_obj =  models. AuthorDetail. objects. filter ( phone= 110 ) . first( ) print ( author_detail_obj. author)  print ( author_detail_obj. author. name)  总结:1.  什么时候加_Set2.  什么时候. all ( ) 结论:当查询的结果是有多个的时候,就需要以上两个操作'''多表查询之连表查询(基于双下划线的查询)''' res =  models. Author. objects. filter ( name= 'jerry' ) . values( 'author_detail__phone' ,  'name' ) print ( res)   res =  models. AuthorDetail. objects. filter ( author__name= 'jerry' ) . values( 'phone' ,  'author__name' ) print ( res)   res =  models. Book. objects. filter ( pk= 1 ) . values( 'publish__name' ,  'title' ) print ( res)   res =  models. Publish. objects. filter ( book__pk= 1 ) . values( 'name' ,  'book__title' ) print ( res)   res =  models. Book. objects. filter ( pk= 1 ) . values( 'authors__name' ) print ( res) res =  models. Author. objects. filter ( book__pk= 1 ) . values( 'name' ) print ( res) res =  models. Book. objects. filter ( pk= 2 ) . values( 'authors__author_detail__phone' ) print ( res)   sum  max  min  avg count
select sum ( price)  from  table group by '' ; 
select avg( price)  from  book; 
from  django. db. models import  Max,  Min,  Sum,  Avg,  Count注意:以后在导模块的时候,只要是跟数据库相关的一般都在
django. db
django. db. models
res =  models. Book. objects. aggregate( Max( 'price' ) ,  Min( 'price' ) ,  Sum( 'price' ) ,  Avg( 'price' ) ,  Count( 'id' ) ) print ( res) 
1.  使用命令修改查看sql_modeshow variables like '%mode%' ; @@select sql_mode; set  global  sql_mode= 'ONLY_FULL_GROUP_BY' 
2.  使用配置文件res =  models. Book. objects. annotate( author_num= Count( 'authors' ) ) . values( 'author_num' ,  'title' ) print ( res) res =  models. Book. objects. annotate( author_num= Count( 'authors__pk' ) ) . filter ( author_num__gt= 1 ) . values( 'author_num' ,  'title' , 'id' ) print ( res) res =  models. Author. objects. annotate( sum_price= Sum( 'book__price' ) ) . values( 'sum_price' ,  'name' ) print ( res) 
	'''F查询''' from  django. db. models import  Fres =  models. Book. objects. filter ( maichu__gt= F( 'kucun' ) ) . all ( ) print ( res[ 0 ] . title) sql:  update book set  price =  price+ 500  ; res =  models. Book. objects. update( price= F( 'price' ) + 500 ) from  django. db. models. functions import  Concatfrom  django. db. models import  Valueres =  models. Book. objects. update( title= Concat( F( 'title' ) ,  Value( '爆款' ) ) ) 
'''Q查询''' from  django. db. models import  Qq =  Q( ) q. connector =  'or' q. children. append( ( "maichu__gt" ,  600 ) ) q. children. append( ( "price__lt" ,  100 ) ) res =  models. Book. objects. filter ( q) print ( res) 1. 事务的四大特性( ACID) 事务的四大特性通常简称为 ACID 特性,它们是数据库管理系统(DBMS)中用于确保事务正确执行和数据的一致性的基本属性。ACID 是由以下四个特性组成:1.  ** 原子性(Atomicity)** :原子性指的是事务是一个不可分割的单位,要么全部执行成功,要么全部执行失败,不存在中间状态。如果事务中的任何操作失败,整个事务会被回滚到初始状态,所有已经执行的操作都会撤销,保证数据库的一致性。2.  ** 一致性(Consistency)** :一致性指的是事务使数据库从一个一致性状态转变为另一个一致性状态。这意味着事务的执行不会破坏数据库中定义的完整性约束和规则,保持数据库数据的正确性。3.  ** 隔离性(Isolation)** :隔离性指的是并发执行的事务之间是相互隔离的,一个事务的执行不应该影响其他事务的执行。事务的隔离性确保了每个事务都感觉自己在独立地操作数据,避免了并发执行时的数据冲突和不一致问题。4.  ** 持久性(Durability)** :持久性指的是一旦事务被提交,其对数据库的修改是永久性的,不会因为系统崩溃或断电而丢失。已提交的事务对数据库的修改会被持久化存储,保证数据的持久性。ACID 特性确保了数据库中的事务正确执行,即使在并发访问的情况下也能维护数据的完整性和一致性。这些特性是数据库管理系统设计的基本原则,用于保证事务的可靠性和数据的可控性。2. 事务的隔离级别事务的隔离级别是数据库管理系统(DBMS)中用于控制并发事务之间相互影响的程度。不同的隔离级别提供了不同的数据一致性和并发性保证。常见的事务隔离级别包括:1.  ** 读未提交(Read Uncommitted)** :最低的隔离级别,在该级别下,事务可以读取其他事务尚未提交的数据。这可能导致脏读、不可重复读和幻读问题。2.  ** 读已提交(Read Committed)** :在该级别下,事务只能读取其他事务已经提交的数据。这可以避免脏读问题,但仍可能出现不可重复读和幻读问题。3.  ** 可重复读(Repeatable Read)** :在该级别下,事务在读取数据时会对其进行加锁,确保其他事务无法修改这些数据。这可以避免脏读和不可重复读问题,但仍可能出现幻读问题。4.  ** 序列化(Serializable)** :最高的隔离级别,在该级别下,事务会对读取的每一行数据都进行加锁,确保其他事务无法读取或修改这些数据。这可以避免脏读、不可重复读和幻读问题,但会降低并发性能。不同的数据库管理系统支持不同的隔离级别,并且默认隔离级别可能因数据库而异。在使用事务时,需要根据具体需求和业务逻辑来选择合适的隔离级别,以平衡数据的一致性和并发性。需要注意的是,较高的隔离级别可能会降低数据库的并发性能,因为它需要使用更多的锁来保证数据的一致性。3. 事务的几个关键1. 开启事务start transaction; 2.  提交事务commit; 3.  回滚事务rollback; 4. 事务的作用:保证安全,保证多个SQL语句要么同时执行成名, 要么同时失败'''Django中如何开启事务''' from  django. db import  transactiontry : with  transaction. atomic( ) : . . . models. Book. objects. filter ( maichu__gt= 100 ,  price__lt= 600 ) . update( ) models. Book. objects. filter ( maichu__gt= 100 ,  price__lt= 600 ) . create( ) except  Exception as  e: print ( e) transaction. rollback( )