目录:
创建多表模型
添加表记录
2.1 一对多新增
2.2 一对多修改数据
2.3 多对多新增
2.4 remove clear set基于对象的跨表查询
3.1 一对一
3.2 一对多
3.3 多对多
3.4 连续跨表基于双下划线的跨表查询
1. 创建多表模型
一对一关系:OneToOneField
本表字段=models.OneToOneField(to='关联的表名',to_field='关联的表的字段')
一对多关系:ForeignKey
本表字段=models.ForeignKey(to='关联的表名',to_field='关联的表的字段')
多对多关系:ManyToManyField
本表字段=models.ManyToManyField(to='关联的表名')
建表:
现建出版社表, 作者表, 作者详情表, 书籍表
'出版社表: 包含id,名字,地址,邮箱字段'
class Publish(models.Model):
id=models.AutoField(primary_key=True)
name=models.CharField(max_length=32)
addr=models.CharField(max_length=64)
email=models.EmailField()
'作者表: ,包含id,姓名,性别,作者详情字段 作者详情字段与作者详情表一对一关系'
class Author(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
sex=models.IntegerField()
authordetail=models.OneToOneField(to='AuthorDetail',to_field='id')
'作者详情表: 包含id,电话号码,地址字段'
class AuthorDetail(models.Model):
id = models.AutoField(primary_key=True)
phone = models.CharField(max_length=32)
addr = models.CharField(max_length=64)
'书籍表: 包含id,姓名,价格,出版社,作者们字段 出版社字段与出版社表一对多,作者们字段与作者表多对多'
class Book(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5,decimal_places=2)
publish=models.ForeignKey(to='Publish',to_field='id')
authors=models.ManyToManyField(to='Author')
注意:
- 用了OneToOneField和ForeignKey,模型表的字段,后面会自定加
_id
- ManyToManyField会自动创建第三张表
2. 增删改表记录
-
一对多新增记录 eg: 添加一本北京出版社出版的书
方式一: 直接存出版社的id ret=Book.objects.create(name='红楼梦',price=34.5,publish_id=1) 方式二: 存对象publish=出版社的对象,存到数据库 publish=Publish.objects.get(id=1)#或者Publish.objects.get(pk=1) ,pk是主键
核心 : 清楚publish与publish_id的区别
-
一对多修改数据
方式一: book=Book.objects.filter(pk=1).update(publish_id=1)#或book=Book.objects.filter(pk=1).update(publish=出版社对象) 方式二: book=Book.objects.get(pk=1) book.publish_id=2#或book.publish=出版社对象
-
多对多新增 eg: 为红楼梦这本书新增一个叫lqz,egon的作者
book对象.add(书籍对象) , 或者book对象.add(书籍id)
'获取作者对象' lqz=Author.objects.filter(name='lqz').first() egon=Author.objects.filter(name='egon').first() '获取书籍对象' book=Book.objects.filter(name='红楼梦').first() '方式一: 添加书籍对象' book.authors.add(lqz,egon) '方式二: 添加书籍id' book.authors.add(1,2)
-
删除之remove : 可以传对象,可以传id,可以传多个, id与对象不要混着用
book.authors.remove(lqz) book.authors.remove(2) book.authors.remove(1,2)
-
清空 clear: 清空所有
清空book这个对象的所有作者
book.authors.clear()
- set:先清空 ,再新增,要传一个列表, 列表内可以是id ,也可以是对象
为book这个对象作者修改为lqz对象
book.authors.set([lqz,])
3. 基于对象的跨表查询
重点 : 基于对象的查询是子查询 , 也就是多次查询
首先了解正反向查询
-
一对一查询
正向查询按字段 eg:查询lqz作者的手机号 author=Author.objects.filter(name='lqz').first() authordetail=author.authordetail print(authordetail.phone) 反向查询按表名小写 eg: 查询地址是 :山东 的作者名字 authordetail=AuthorDetail.objects.filter(addr='山东').first() author=authordetail.author print(author.name)
-
一对多
正向查询按字段 eg:查询红楼梦这本书的出版社邮箱 book=Book.objects.filter(name='红楼梦').first() pulish=book.publish print(pulish.email) 反向查询按表名小写_set.all() eg: 查询地址是北京 的出版社出版的图书 publish=Publish.objects.filter(addr='北京').first() books=publish.book_set.all().values('name') print(books)
-
多对多
正向查询按字段 eg: 查询红楼梦这本书所有的作者 book=Book.objects.filter(name='红楼梦').first() authors=book.authors.all().values('name') print(authors) 反向查询按表名小写_set.all() eg: 查询lqz写的所有书 lqz=Author.objects.filter(name='lqz').first() books=lqz.book_set.all().values('name') print(books)
-
连续跨表 eg: 查询红楼梦这本书所有的作者的手机号
authors=Book.objects.filter(name='红楼梦').first().authors.all() for author in authors: num=author.authordetail.phone print(num)
4. 基于双下划线的查询
-
一对一
eg: 查询 lqz 作者的手机号 正向按字段 以author表作为基表 ret=Author.objects.filter(name='lqz').values('authordetail__phone') 反向查询,按表名小写 以authordetail作为基表 ret=AuthorDetail.objects.filter(author__name='lqz').values('phone') eg: 查询lqz这个作者的性别和手机号 正向 ret=Author.objects.filter(name='lqz').values('sex','authordetail__phone') eg:查询手机号是13888888的作者性别 ret=Author.objects.filter(authordetail__phone='13888888').values('sex') ret=AuthorDetail.objects.filter(phone='13888888').values('author__sex')
-
多对多与跨表查询, 用法与一对一 一样也是用双下划线__来跨表
eg: 查询出版社为北京出版社出版的所有图书的名字,价格 Publish.objects.filter(name='北京出版社').values('book__name','book__price') 或者 Book.objects.filter(publish__name='北京出版社').values('name','price') eg:查询北京出版社出版过的所有书籍的名字以及作者的姓名 Publish.objects.filter(name='北京出版社').values('book__name','book__authors__name') 或者 Book.objects.filter(publish__name='北京出版社').values('name','authors__name')