Django学习之模型层---多表操作之增
1>介绍
先回顾下之前数据库的多表之间的对应关系
--->一对多,表A的记录可以对应表B的多条记录(如出版社和书本关系,一个出版社可以出版多本书,一本书只能属于
一个出版社),这个时候表A要跟表B建立连接,就必须在表B上面,增加一个关联字段,用外键指向表A的字段。
--->多对多,表A的多条记录可以对应表B的多条记录(如作者和书本关系,可以多个作者联名发布一本书,一个作者也
可以发布多本书),这个时候表A要跟表B建立关系,就必须单独建立一张关系表,关系表包含3列,一列是该表的主键,
一列用外键指向表A的字段,另一列用外键指向表B的字段,以此来建立他们的关系。
--->一对一,表A的一条记录对应表B的一条记录,其实就类似于一张表拆成两张表,有是数据表过大,这样解耦是为了
取值方便,所以拆成了两张,这个时候两张表要建立连接,就可以再任意一张表上面增加关联字段,用外键指向另一张表
的字段,只是这里,关联字段必须加上 unique约束,
下面我们看下Django中怎么建立这些表。
2>ORM中建立一对一关系的语法
实际效果如下:
3>ORM中建立一对多关系的语法
实际效果如下:
4>ORM中建立多对多关系的语法
实际效果如下:
5>稍做总结
先看下之前orm语法的效果
authorDetail=models.OneToOneField(to="AuthorDetail",to_field='nid', on_delete=models.CASCADE)
publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE)
authors=models.ManyToManyField(to='Author',)
前两句做列的关联,对应的表中会自动生成 xx_id字段,如 authorDetail_id 和publish_id,关键字参数 to 后面
接的就是表名,to_field为列名,若列名是该表的主键,则这个参数也可以不写,django 1版本默认会加上这个
删除关联校验,但是2.0取消了,所以,必须手动加上 on_delete=models.CASCADE,另外,ForeignKey里面
还有个null=True的参数,类似非空约束了,写上就表示可以为空。
而最后一句多对多的关联,则是生成一张新的表,表的主键为 xx_id,如这里是author_id,列名就是两张表的
名称加上_id,关联至对应表的主键。
所以, 一定要搞清楚这里的语法,就是做了啥,外键和OneToOne是生成列,而ManyToMany是生成表。
6>数据插入
单表操作就不说了(没有外键或OneToOne关联数据的),之间之前的方法创建对象就是。
重点说一下一对多 和多对多的数据写入
6.1>一对多
6.2>多对多
多对多记录的插入,先看下要准备的数据,插入一条数据要准备两个值,如上面boook_id和author_id,
在ORM里面对应就是对应的 书籍对象和 作者对象,把他们做关联,所以,要先查询出或者创建这些对象
先回忆多对多的第三张表是怎么生成的
没错,就这句,因为第三张表并不是跟其他表一样,通过class xxx 创建的,他是在这个Boook下面通过语法,
Django直接在数据库创建的表,先记下上面绑定的关系的语法,Boook对象.authors.add(对象1,对象2,....)
这个authors就相当于Boook类或者Boook对象的一个属性,所以可以用点语法引用,再调用固定方法add,把要关联
的对象添加进来,这就是实现了在第三张表插入多对多数据的效果,如上,Boook对象添加了两个作者对象
所以,数据库肯定也同步生成了两条记录
补充一点疑虑:
可能很多人会想,这个语法虽然简介,但是确实不太好理解,多对多表添加表记录,我难道不可以像之前一样,
直接类似Book.objects.create(xx1=xxx,xx2=xx,xx3=xx)这样,插入数据呢?
答案是:不能,请看下图
插入数据的语法,你首先要有这张表,但是,django的orm这里根本没张表,上面说了,这张表是通过一行语法代码
直接在数据库生成的,这里是根本引用不到的,表(对应python的类)都没,还怎么调用后面的create语法呢?
最后再提一下重点中的重点:
1>book_obj.publish与book_obj.publish_id(一对多表的记录添加方式1和方式2)
2>book_obj.authors.all()(多对多表的记录添加,理解authors以及这个all()的返回值)