Django 多表操作
创建多表模型
在settings内配置好database
在项目下的models内创建表的模型
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()
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')
class AuthorDetail(models.Model):
id = models.AutoField(primary_key=True)
phone = models.CharField(max_length=32)
addr = models.CharField(max_length=64)
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')
在项目文件夹下的_ _ init _ _.py文件内写入
import pymysql
pymysql.install_as_MySQLdb()
再在命令窗口内输入
python3 manage.py makemigrations
python3 manage.py migrate
一对多新增数据
一对多新增数据
#添加一本北京出版社出版的书
#第一种方式
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)
多对多 增删
#为红楼梦这本书新增一个叫layer,dzg的作者
lqz=Author.objects.filter(name='layer').first()
egon=Author.objects.filter(name='dzg').first()
book=Book.objects.filter(name='红楼梦').first()
# add 添加多个对象
book.authors.add(layer,dzg)
#add添加作者id
book.authors.add(1,2)
#删除 remove,可以传对象,可以传id,可以传多个,不要混着用
book.authors.remove(layer)
book.authors.remove(2)
book.authors.remove(1,2)
#clear清空所有
book.authors.clear()
#set,先清空,在新增,要传一个列表,列表内可以是, id,也可以是对象
book.authors.set([layer,])
#这样不行,因为它打散了传过去了,相当于book.authors.set(lqz)
book.authors.set(*[layer,])
基于对象的跨表查询
一对一
正向 author---关联字段在author--->authordetail ------> 按字段
反向 authordetail------关联字段在author--->author -----> 按表名小写
#查询layer作者的手机号 正向查询
author=Author.objects.filter(name='layer').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())
#查询layer写的所有书
lqz=Author.objects.filter(name='layer').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)
基于对象的查询---是子查询也就是多次查询
基于双下划线的查询
#一对一
#查询layer作者的手机号 正向查询 跨表的话,按字段
#以author表作为基表
ret=Author.objects.filter(name='layer').values('authordetail__phone')
print(ret)
#以authordetail作为基表 反向查询,按表名小写 跨表的话,用表名小写
ret=AuthorDetail.objects.filter(author__name='layer').values('phone')
print(ret)
#查询layer这个作者的性别和手机号
#正向
ret=Author.objects.filter(name='layer').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)