11. django多表查询part1
django多表查询part1
- 一、多表操作之模型创建
- 1、多张表的关系:
- 2、 models.py中建立出来
- 3、同步到mysql数据库
- 4、 注意点:
- 二、一对多添加表记录
- 三、多对多添加、修改、删除记录
- 四、基于对象的跨表查询(重点)
- 1、基于对象的跨表查询(子查询):
- 2、基于双下划线的跨表查询
- 五、连续跨表
一、多表操作之模型创建
1、多张表的关系:
1、图书表:book,作者表:author,作者详情表:author_detail,出版社表:publish,作者与书之间的中间表
2、作者和作者详情:是一对一,关联字段写在哪一方面都可以
3、图书和出版社:是一对多,一对多关系一旦确立,关联字段写在多的一方
4、图书和作者:是多对多,多对多的关系需要建立第三张表(可以自动生成)
2、 models.py中建立出来
from django.db import modelsclass Publish(models.Model):id = models.AutoField(primary_key=True)name = models.CharField(max_length=32)addr = models.CharField(max_length=64)phone = models.CharField(max_length=64)email = models.EmailField()class Book(models.Model):id = models.AutoField(primary_key=True)name = models.CharField(max_length=32)price = models.DecimalField(max_digits=6, decimal_places=2)publish_date = models.DateTimeField(auto_now_add=True)# to='Publish'跟Publish表做关联(ForeignKey,一对多)# to_field='id'跟哪个字段做关联# publish=models.CharField(max_length=32)# publish=models.ForeignKey(to='Publish',to_field='id')# publish = models.ForeignKey(to='Publish') # 不写to_field,默认跟主键做关联publish = models.ForeignKey(to=Publish) # 已经创建了Publish字段就可以不加引号# 自动创建出第三张表# authors在数据库中不存在该字段,没有to_field# 默认情况:第三张表有id字段、当前Book表的id和Author表的id字段authors=models.ManyToManyField(to='Author')class Author(models.Model):id = models.AutoField(primary_key=True)name = models.CharField(max_length=32)age = models.SmallIntegerField()# 一对一的本质是 ForeignKey+uniqueauthor_detail=models.OneToOneField(to='AuthorDetail',to_field='id')# author_detail=models.ForeignKey(to='AuthorDetail',to_field='id',unique=True)class AuthorDetail(models.Model):id = models.AutoField(primary_key=True)sex = models.SmallIntegerField()addr = models.CharField(max_length=64)phone = models.BigIntegerField()
3、同步到mysql数据库
# 配置文件:DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'book001', # 数据库中的book001数据库必须是个新数据库,否则迁移会失败'HOST': '127.0.0.1','PORT': 3306,'USER': "root","PASSWORD": '111'}
}# app中的__init__.py中写:import pymysqlpymysql.install_as_MySQLdb()# 数据库迁移两条命令:- python3 manage.py makemigrations- python3 manage.py migrate
4、 注意点:
# 2.x版本的django中:- 外键字段必须加, 参数on_delete不能少- 1.x版本则不需要,on_delete默认就是CASCADE(级联删除)- 示例:on_delete=models.CASCADE 删除出版社,该出版社的所有图书也都会被删除on_delete=models.SET_NULL,null=True 删除出版社,该出版社出版的图书不删除,关联字段设置为空on_delete=models.SET_DEFAULT,default=0 删除出版社,该出版社的图书不删除,ForeignKey设置成默认的(必须是int类型)# id字段是自动添加的
# 对于外键字段,django会在字段名上加后缀“_id”来创建数据库中的列名
# 外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None
二、一对多添加表记录
publish1 = models.Publish.objects.create(name='少林出版社', addr='河南嵩山', phone='0371-12345678',email='shaolinchubanshe@qq.com')# 新增龙抓手图书
book=models.Book.objects.create(name='龙抓手',price='23.45',publish=publish1)# publish=对象# book=models.Book.objects.create(name='西游记',price='23.55',publish_id=1)# publish_id=数字# 新增西游记
book=models.Book.objects.create(name='西游记',price='23.55',publish_id=publish.id) # publish_id=数字
总结:
# 0、一对多的关系中,先创建“一”的那个对象,因为在“多”的对象创建时,必须给外键字段传值
# 1、email字段可以不传真正的email,本质就是varchar(继承的CharField),在admin中会判断是不是email格式
# 2、新增图书设置publish字段:- publish=pubklish- publish_id=publish.id- publish=数字
# 3、写在表模型中的publish字段,到数据库中会变成publish_id(ForeignKey)
# 4、查到book对象后,可以用对象.publish 和对象.publish_id- book.publish 对象- book.publish_id id号,数字
三、多对多添加、修改、删除记录
常用的API:
book.authors.add() # 给特定的对象增加被关联的对象
book.authors.remove() # 将某个特定的对象从被关联的对象集合中去除
book.authors.clear() # 清空被关联对象集合
book.authors.set() # 先清空后设置(重新设置的育原来一样的话就不清空,id不改变)
1、自动添加创建的表(中间表)的模型是取不到的,book.authors代表模型# 取到name叫易筋经的这本书book = models.Book.objects.get(name='易筋经')# book.authors这个字段代指的就是中间表damo = models.Authors.objects.get(id=1)cc = models.Authors.objects.get(id=2)book.authors.add(damo,cc) # 新增作者,通过对象新增:# 也可以通过id新增,或者混合使用id和对象# book.authors.add(1,2)# book.authors.add(1,cc)# remove 移除book.authors.remove(2)# book.authors.remove(cc)# clear 清空所有的作者book.authors.clear()# set 先清空在新增作者,(新增的是原来不存在的作者,原来就有的作者不清空,也不增加)book.authors.set([3,4])
四、基于对象的跨表查询(重点)
跨表查询有两种方式:
- 基于对象的跨表查询:子查询
- 基于双下划线的跨表查询:关联查询、连表查询
1、基于对象的跨表查询(子查询):
- 一对多查询(publish与book)
# 正向查询:按字段publish- 查询主键为1的书籍的出版社所在的城市book = models.Book.objects.filter(id=1).first()publish = book.publish # 主键为1的书籍对象关联的出版社对象print(publish.addr)# 反向查询:按表名 book_set- 北京出版社的所有的书的名字publish = models.Publish.objects.get(name='北京出版社')books = publish.book_set.all()for book in books:print(book.name)
- 一对一查询(Author与AuthorDetail)
# 正向查询:按字段Authordetail- 查询egon作者的地址author=models.Author.objects.get(name='egon')print(author.author_detail.addr)# 反向查询:按小写表名author- 查询住在北京的作者的名字authordetails = models.AuthorDetail.objects.filter(addr='北京')for obj in authordetails:print(obj.author.name)
- 多对多查询(Author与Book)
# 正向查询:按字段authors- 查询西游记所有作者的的名字和手机号book = models.Book.objects.filter(name='西游记').first()authors = book.authors.all()for author in authors:print(author.name, author.author_detail.phone)# 反向查询:按表名book_set- 查询作者cc出过的所有的书籍的名字cc = models.Author.object.get(name='cc')books = cc.book_set.all()for book in books:print(book.name)
2、基于双下划线的跨表查询
- 一对多查询
# 正向查询:按字段名
# 反向查询:按表名小写# filter, values, values_list(写__ 跨表)- 查询北京出版社出版过的所有书籍的名字与价格(一对多)# 基于publish表res=models.Publish.objects.filter(name='北京出版社').values('book__name','book__price')print(res)# 基于book表res=models.Book.objects.filter(publish__name='北京出版社').values('name','price')print(res)
- 多对多查询
- 查询cc出过的所有书籍的名字,价格(多对多)
# 反向
res = models.Author.objects.filter(name='cc').value('book__name','book__price')
print(res)# 正向
res = models.Book.objects.filter(author__name='cc').values('name','price')
print(res)
- 一对一
- 查询cc的手机号
res=models.Author.objects.filter(name='cc').value('author_detail__phone')
print(res)res=models.AuthorDetail.objects.filter(author__name='cc').values('phone')
print(res)
五、连续跨表
- 查询北京出版社出版过的所有书籍的名字以及作者的姓名# 方式一res=models.Publish.objects.filter(name='北京出版社').values('book__name','book__authors__name')print(res)# 方式二res=models.Book.objects.filter(publish__name='北京出版社').values('name','authors__name')print(res)# 方式三res=models.Author.objects.filter(book__publish__name='北京出版社').value('book__name','name')- 手机号以137开头的作者出版过的所有 书籍名称 以及 出版社名称res = models.AuthorDetail.objects.filter(phone__startswith='137').values('author__book__name','author__book__publish__name')print(res)res = models.Author.objects.filter(author_detail__phone__startswith='137').values('book__name','book__publish__name')print(res)
11. django多表查询part1相关推荐
- Django | 跨表查询
一:创建表 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many); 一本书只应该由一个出版商出版,所以 ...
- Django多表查询练习题
#一 model表:from django.db import models# Create your models here.class Teacher(models.Model):tid=mode ...
- django 单表查询
一 ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人 ...
- Python Django单表查询之日期查询(大于小于范围查询)
- day056-58 django多表增加和查询基于对象和基于双下划线的多表查询聚合 分组查询 自定义标签过滤器 外部调用django环境 事务和锁...
一.多表的创建 from django.db import models# Create your models here. class Author(models.Model):id = model ...
- Django的多表查询操做
今日内容概要 1 > 神奇的双下划线查询 1 > 查询年龄大于20的用户 2 > 查询年龄是18.22.25的用户 3 > 查询年龄在18到26之间的用户 4 > 查询姓 ...
- 065.django之多表查询
文章目录 一 创建模型 (一) 模型创建 (二) 外键关系建立问题 二 添加表记录 (一) 一对多添加记录 (二) 多对多添加记录 (三) 多对多关系常用的API 三 基于对象的跨表查询 (一) 两种 ...
- Django 6 模型与数据库 (2) 各种查询操作以及多表查询
Django通过模型迁移除数据库的数据表,又提供了操作数据模型的API来实现对目标数据库的读写操作.数据库的读写操作主要对数据进行增.删. 改.查. Django带有shell模式(启动命令行和执行脚 ...
- day17-python项目Django之跨表查询及Ajax、cookie和session
第1章 课堂笔记 class (models.Model):title=models.CharField(max_length=32)price=models.DecimalField(max_dig ...
最新文章
- 修改DEDECMS文章标题长度,解决DEDECMS文章标题显示不全
- OSX unable to write 'random state'
- [读书笔记]C#学习笔记二: 委托和事件的用法及不同.
- 用户资源管理DBMS_RESOURCE_MANAGER
- 【转】排序算法复习(Java实现) (二): 归并排序,堆排序,桶式排序,基数排序...
- 谁是颠覆者?最全盘点25条区块链主链
- python数组初始化_Python Numpy 数组的初始化和基本操作
- 【Python的黑魔法】实例方法、静态方法和类方法
- html改元素怎么保存,是否可以在NW.js中保存html元素更改?
- 2021年低碳科技白皮书
- angular模态框位置_angular $modal 模态框
- Java基础学习总结(41)——JPA常用注解
- centos系统的Visual Studio code卡死,无法选择或者输入
- threadlocal原理_Java并发编程——揭开ThreadLocal的面纱
- Java自动化测试——打开浏览器
- 渗透测试常用工具-端口扫描
- android mac地址 伪装,教你伪装MAC地址
- 机器人读懂人心的九大模型
- MOOC《程序设计入门——C语言》翁恺 第六周编程练习及答案
- 成君忆不幸被彭剑锋言中