一对多新增数据
添加一本北京出版社出版的书
第一种方式
ret=Book.objects.create(name='红楼梦',price=34.5,publish_id=1)
print(ret.name)
第二种方式,存对象publish=出版社的对象,存到数据库,是一个id
publish=Publish.objects.get(id=1)
pk是主键,通过主键查找
publish=Publish.objects.get(pk=1)
publish = Publish.objects.filter(pk=2).first()
ret = Book.objects.create(name='西游记', price=34.5, publish=publish)
print(ret.name)
一对多修改数据
book=Book.objects.get(pk=1)
book.publish=出版社对象
book.publish_id=2
book.save()
方式二
book=Book.objects.filter(pk=1).update(publish=出版社对象)??
book=Book.objects.filter(pk=1).update(publish_id=1)
多对多新增
为红楼梦这本书新增一个叫lqz,egon的作者
lqz=Author.objects.filter(name='lqz').first()
egon=Author.objects.filter(name='egon').first()
book=Book.objects.filter(name='红楼梦').first()
add 添加多个对象
book.authors.add(lqz,egon)
add添加作者id
book.authors.add(1,2)
删除 remove,可以传对象,可以传id,可以传多个,不要混着用
book.authors.remove(lqz)
book.authors.remove(2)
book.authors.remove(1,2)
clear清空所有
book.authors.clear()
set,先清空,在新增,要传一个列表,列表内可以是, id,也可以是对象
book.authors.set([lqz,])
********这样不行,因为它打散了传过去了,相当于book.authors.set(lqz)
book.authors.set(*[lqz,])
lqz=Author.objects.filter(name='lqz')
print(type(lqz))
from django.db.models.query import QuerySet
***************************基于对象的跨表查询
'''
一对一
正向 author---关联字段在author--->authordetail ------> 按字段
反向 authordetail------关联字段在author--->author -----> 按表名小写
'''
查询lqz作者的手机号 正向查询
author=Author.objects.filter(name='lqz').first()
author.authordetail 就是作者详情的对象
authordetail=author.authordetail
print(authordetail.phone) 查询地址是 :山东 的作者名字 反向查询 authordetail=AuthorDetail.objects.filter(addr='山东').first() authordetail.author 这是作者对象 author=authordetail.author print(author.name)
一对多
'''
一对多
正向 book---关联字段在book--->publish ------> 按字段
反向 publish------关联字段在book--->book -----> 按表名小写_set.all()
'''
正向 查询红楼梦这本书的出版社邮箱
book=Book.objects.filter(name='红楼梦').first()
book.publish 就是出版社对象
pulish=book.publish
print(pulish.email)
反向 查询地址是北京 的出版社出版的图书
publish=Publish.objects.filter(addr='北京').first()
publish.book_set.all() 拿出所有的图书
books=publish.book_set.all()
统计一下条数
books=publish.book_set.all().count()
print(books)
'''
多对多
正向 book---关联字段在book--->author ------> 按字段.all()
反向 author------关联字段在book--->book -----> 按表名小写_set.all()
'''
查询红楼梦这本书所有的作者
book=Book.objects.filter(name='红楼梦').first()
book.authors.all() 是所有的作者,是一个queryset对象,可以继续点
print(book.authors.all())
查询lqz写的所有书
lqz=Author.objects.filter(name='lqz').first()
books=lqz.book_set.all()
print(books)
连续跨表
查询红楼梦这本书所有的作者的手机号
book=Book.objects.filter(name='红楼梦').first()
authors=book.authors.all()
for author in authors:
authordetail=author.authordetail
print(authordetail.phone)
****************************基于对象的查询---是子查询也就是多次查询
***************基于双下划线的查询*****
一对一
查询lqz作者的手机号 正向查询 跨表的话,按字段
以author表作为基表
ret=Author.objects.filter(name='lqz').values('authordetail__phone')
print(ret)
以authordetail作为基表 反向查询,按表名小写 跨表的话,用表名小写
ret=AuthorDetail.objects.filter(author__name='lqz').values('phone')
print(ret)
查询lqz这个作者的性别和手机号
正向
ret=Author.objects.filter(name='lqz').values('sex','authordetail__phone')
print(ret)
查询手机号是13888888的作者性别
ret=Author.objects.filter(authordetail__phone='13888888').values('sex')
print(ret)
ret=AuthorDetail.objects.filter(phone='13888888').values('author__sex')
print(ret)
1 创建多表模型(详情见代码)
用了OneToOneField和ForeignKey,模型表的字段,后面会自定加_id
ManyToManyField会自动创建第三张表
一对一的关系:OneToOneField
一对多的关系:ForeignKey
多对多的关系:ManyToManyField
2 添加表记录
1 一对多新增
-两种方式:
-publish=对象
-publish_id=id
2 一对多删除:同单表删除
3 一对多修改:两种方式,可以传对象,可以传id
4 一对一跟一对多一样
5 多对多:
-add ----->可以传对象,可以传id,可以传多个
-remove ----->可以传对象,可以传id,可以传多个
-clear ---->没有参数
-set ----->跟上面不一样,必须传列表,列表里面可以是对象,可以是id
3 基于对象的跨表查询
1 一对一
正向:正向查询按字段
反向:反向查询按表名小写
2 一对多
正向:正向查询按字段
反向:反向按表名小写_set.all()
3 多对多
正向:正向查询按字段
反向查询:反向按表名小写_set.all()
4 基于双下划线的跨表查询
-连表查询
-一对一双下划线查询
-正向:按字段,跨表可以在filter,也可以在values中
-反向:按表名小写,跨表可以在filter,也可以在values中
id如果不写,会自动生成,名字叫nid,并且自增
可以用ForeignKey,但是得设置唯一性约束,会报警告,不建议用,建议用OneToOneField
authordetail=models.ForeignKey(unique=True)
to='AuthorDetail' 加引号,这个表能找到就可以,不用引号,类必须在上面定义
用了OneToOneField和ForeignKey,模型表的字段,后面会自定加_id
ManyToManyField会自动创建第三张表
一对一的关系:OneToOneField
一对多的关系:ForeignKey
多对多的关系:ManyToManyField