本节内容:

1、回顾一对一、一对多、多对多的表结构关系
2、创建模型
3、添加表记录
4、基于对象的跨表查询
5、基于双下划线的跨表查询
6、聚合查询与分组查询
7、F查询与Q查询

一、回顾一对一、一对多、多对多的表结构关系

1、一对多关系表

一本书只有一个出版社,一个出版社可以出版多本书
关联字段在“多”的表中
book
id  title  publish_id
1   java       1
2   go         1 publish id name email addr 1 AAA 123 bejing 
SQL
Copy

2、多对多创建关系表

表之间的关系,书和作者的关系,一本书可以有多个作者,一个作者可以有多本书
多对多创建关系表Book表id  title  publish_id1   java       12   go         1 Author表 id name 1 alex 2 yuan book2author对应关系表(借助第三张表) id book_id author_id 1 1 1 2 1 2 3 2 2 
SQL
Copy

3、一对一关系表

关联字段可以建立在任意表下,但必须唯一约束。
Authorid name  ad_id(unique约束)1 alex 1 2 yuan 2 AuthorDetail id gender addr gf ID author_id 1 male beijing 铁锤 131 1 2 male beijing 钢弹 151 2 
SQL
Copy

二、创建模型

1、 实例:图书管理

我们来假定下面这些概念,字段和关系作者模型:一个作者有姓名和年龄。作者详细模型:
把作者的详情放到详情表,包含生日,手机号,家庭住址等信息。
作者详情模型和作者模型之间是一对一的关系(one-to-one)出版商模型: 出版商有名称,所在城市以及email。书籍模型:  书籍有书名和出版日期,
一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);
一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many) 
Bash
Copy

book这个app下的models.py文件代码

from django.db import models# Create your models here. class Book(models.Model): title = models.CharField( max_length=32) pub_date=models.DateField() price=models.DecimalField(max_digits=5,decimal_places=2) # 与Publish建立一对多的关系,外键字段建立在多的一方 publish=models.ForeignKey(to="Publish",to_field="id",on_delete=models.CASCADE,null=True) # 字段名默认为,publish_id ,on_delete级联删除,删一个其他的跟着删除 # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors=models.ManyToManyField("Author",db_table="book2authors") # 创建关系表, db_table关系表的名字可以在这里设定 def __str__(self): return self.title class Publish(models.Model): name=models.CharField( max_length=32) city=models.CharField( max_length=32) email=models.CharField(max_length=32) def __str__(self): return self.name class Author(models.Model): name=models.CharField( max_length=32) age=models.IntegerField() #books=models.ManyToManyField("Book") ad=models.OneToOneField("AuthorDetail",null=True,on_delete=models.CASCADE) def __str__(self): return self.name class AuthorDetail(models.Model): birthday=models.DateField() telephone=models.BigIntegerField() addr=models.CharField( max_length=64) # author=models.OneToOneField("Author",on_delete=models.CASCADE) def __str__(self): return str(self.telephone) 
Python
Copy

2、写这个表格对象的python代码的—注意事项

1、表的名称myapp_modelName,是根据 模型中的元数据自动生成的,
也可以覆写为别的名称,就是重命名2、id字段默认会自动添加且为主键,可以不写,3、对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名所以我们在写外键字段时,就只写关联的表名4、这个例子中的CREATE TABLE SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。5、定义好模型之后,你需要告诉Django _使用_这些模型。
你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加models.py所在应用的名称6、外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。
Bash
Copy

二、添加表记录

添加记录前的准备工作,创建好数据库,
1、选择MySQL数据库(常用),还是sqlite3数据库,看需求。
DATABASES = {'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'day056orm', # 要连接的数据库,连接前需要创建好 'USER':'root', # 连接数据库的用户名 'PASSWORD':'123', # 连接数据库的密码 'HOST':'127.0.0.1', # 连接主机,默认本级 'PORT':3306 # 端口 默认3306 }, } 注意:使用MySQL数据库时记得在启动文件夹下的__init__文件中, 添加import pymysql pymysql.install_as_MySQLdb() 然后启动python manage.py makemigrations命令和python manage.py migrate 就创建好了,我们写好的表结构。 
Bash
Copy

1、创建一些基础表(被关联的表)

创建publish表

创建author表

创建authordetail表:

2、绑定关系

首先在urls.py中绑定好urls分发,path('add/',views.add),
在book的app下创建好,def add(request):视图函数

1、绑定一对多的关系

创建表记录及绑定其对应的关系

def add(request): # 绑定一对多关系 # 创建书籍和出版社 # 方式1: # book=models.Book.objects.create(title="linux",price=122,pub_date="2012-12-12",publish_id=1) # 方式2: # pub_obj=models.Publish.objects.filter(name="人民出版社").first() # 拿到publish对象 # book=models.Book.objects.create(title="python",price=223,pub_date="2012-11-11",publish=pub_obj) # print(book.publish_id) # print(book.publish) # book书籍的出版社对象 # 查询python书籍的出版社的邮箱 # 方式1,双下划线查询 # email=models.Book.objects.filter(title="python").values("publish__email") # print(email) # email=models.Publish.objects.filter(id=book.publish_id).first().email # book是上面的表记录对象 # print(email) # print(book.publish.email) return HttpResponse("创建成功") 核心: book.publish和book.publish_id具体是什么? 1、book.publish # 直接拿到的是出版社对象, 2、book.publish_id # 拿到是出版社对象对应的id 
Python
Copy

2、绑定多对多关系

绑定多对多的关系, 无非就是在关系表中创建记录

绑定多对多关系

# linux这本书绑定两个作者: alex,egon# linux=models.Book.objects.filter(title="linux").first()
# alex=models.Author.objects.filter(name="alex").first()
# egon=models.Author.objects.filter(name="egon").first() # linux.authors.add(alex,egon) # Book对象直接点外键字段,就可以找到第三张关系表 # # linux.authors.add(1) # 为这个Book对象添加一个作者, # linux.authors.add(*[1,2]) # 打散列表,为该书籍添加列内的所有作者 # # linux.authors.remove(alex,) # 为该书籍删除一个作者 # linux.authors.clear() # 清空该Book对象的关系表的关联关系 # # linux.authors.set([1,]) # set先清空之前所有的记录(作者),重新写入,类似于文件写入前清空 # 绑定多对多关系,重点是在关系表上创建记录,做好两个表之间的对应关系 ######### 正向操作按字段,反向操作按表名小写 linux = models.Book.objects.filter(title='linux').first() go = models.Book.objects.filter(title="go").first() alex = models.Author.objects.filter(name="alex").first() # 给alex作者绑定两本书籍: linux,go alex.book_set.add(linux,go) # 单个的时候直接操作,多个对象是使用_set操作 核心:book_obj.authors.all()是什么? 待续 
Python
Copy

四、基于对象的跨表查询

一 基于对象的跨表查询( 子查询:以上一次的查询结果作为下一次的查询条件)(1)一对多正向查询:按字段 book.publishBook对象(多)---------------------------------- > Publish 对象 <--------------------------------- 反向查询:按表名小写_set.all() (2)多对多 正向查询:按字段 book.authors.all() Book对象 ---------------------------------- > Author 对象 <--------------------------------- 反向查询:按表名小写_set.all() (2)一对一 正向查询:按字段 book.ad Author 对象 ---------------------------------- > AuthorDetail 对象 <--------------------------------- 反向查询:按表名小写 
Bash
Copy

基于对象的跨表查询

def query(request): #(1)一对多 # 1 查询linux这本书的出版社的城市(正向查询) # book=models.Book.objects.filter(title='linux').first() # print(book.publish.city) # Book对象直接点外键字段就是出版社对象,直接点城市就行了 # 2 查询人民出版社出版的所有书籍(反向查询) # publish=models.Publish.objects.filter(name='人民出版社').first() # queryset=publish.book_set.all() # 这是拿到的是一个集合 # print(queryset) # <QuerySet [<Book: linux>, <Book: python>]> # 2、多对多 # 1 查询linux书籍的所有作者(正向查询) # linux=models.Book.objects.filter(title="linux") # queryset=linux.authors.all() # 这样就可以拿到所有的书籍对象集合,因为设置了__str__ # print(queryset) # 2 查询alex作者出版过的所有书籍 # alex=models.Author.objects.filter(name='alex').first() # 记得从集合中取出第一个对象 # queryset=alex.book_set.all() # 反向查询表名_set # print(queryset) # <QuerySet [<Book: linux>]> # 3 一对一 # 1 查询alex的手机号 # alex=models.Author.objects.filter(name="alex").first() # print(alex.ad.telephone) # 2 查询手机号为110的作者的名字 # tel=models.AuthorDetail.objects.filter(telephone=911).first() # print(tel.author.name) # 不是集合对象,直接表名(小写).出来 return HttpResponse("查询成功") 
Python
Copy

五、基于双下划线的跨表查询

KEY:通知ORM引擎如何跨表: 正向查询按字段,反向查询按表名小写

基于双下划线的跨表查询

def query(request): # 1、查询linux这本书的出版社地址 # 方式1 正向查询 # queryset=models.Book.objects.filter(title="linux").values("publish__city") # print(queryset) # filter得到的queryset集合对象 # 方式2 反向查询 # queryset=models.Publish.objects.filter(book__title="linux").values("city") # print(queryset) # 2 查询linux书籍的所有作者 # queryset=models.Book.objects.filter(title="linux").values("authors__name") # queryset=models.Book.objects.filter(title__startswith="li").values("authors__name") # 重点 # print(queryset) # queryset=models.Author.objects.filter(book__title="linux").values("name") # 反向查询 # 3 查询alex的手机号 # queryset=models.Author.objects.filter(name="alex").values("ad__telephone") # 正向 # queryset=models.AuthorDetail.objects.filter(author__name="alex").values("telephone") # 反向 # print(queryset) # 连续跨表 # 4 查询人民出版社出版过的所有书籍的名字及作者的姓名 queryset=models.Book.objects.filter(publish__name="人民出版社").values("title","authors__name") # 正向查询 # queryset=models.Author.objects.filter(book__publish__name="人民出版社").values("book__title","name") # 反向查询 # 默认都是left join,所以如果有存在的左边基准的值为空,那么就会不保留这条记录 print(queryset) return HttpResponse("查询成功")

转载于:https://www.cnblogs.com/yipianshuying/p/10223411.html

day055056Django之多表操作,多表查询相关推荐

  1. SQL2K数据库开发十五之表操作查看表中的数据

    1.可以使用SELECT语句查询表中的数据.如在查询分析器中执行SELECT * FROM Products语句就可以查询Products表中的数据,如下图: 2.如在企业管理器中查询表中数据,则要展 ...

  2. MySQL 表关系及多表操作(联合查询、连接查询、子查询)

    文章目录 表关系 一对一关系 一对多关系 多对多关系 总结 MySQL多表操作 联合查询 联合查询排序 连接查询 交叉连接 内连接 外连接 自然连接 using关键字 子查询 表关系 表关系:一个表代 ...

  3. SQL Server 2005系列教学(6) 多表操作及子查询

    多表查询:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> 人事 ...

  4. mysql的多表操作_Mysql-多表连接的操作和用法

    一.介绍 本节主题 多表连接查询 复合条件连接查询 子查询 准备表 #建表 create table dep( id int, name varchar(20) ); create table emp ...

  5. MySQL表操作-创建表/删除表/修改表

    一.创建表 CREATE TABLE 表名( 字段1 类型 [约束], //中括号的意思是可选项 字段2 类型 [约束], ... ..., 字段n 类型 [约束] ); 二.删除表 DROP TAB ...

  6. Django 【第六篇】ORM跨表操作(聚合查询,分组查询,F和Q查询等)

    一:创建表 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);     一本书只应该由一个出版商出 ...

  7. mysql表操作_MySQL表操作语句用法百科

    本文采用MySQL5.7.26版本 1 建表语句 建表语句create语法如下: 1.1 设置unsigned unsigned设置数值类型是否为无符号数,可以为空,如下举例: 1.2 设置默认值 d ...

  8. 线性表操作(线性表)

    Description (线性表)请你定义一个线性表,可以对表进行"在某个位置之前插入一个元素"."删除某个位置的元素"."清除所有元素". ...

  9. MySQL从入门到精通50讲(四)-MySQL表操作创建表及删除表

    前言 声明:以下是博主精心整理的机器学习和AI系列文章,博主后续会不断更新该领域的知识: 人工智能AI实战系列代码全解析 手把手教你ML机器学习算法源码全解析 有需要的小伙伴赶紧订阅吧. MySQL ...

  10. SpringDataJpa (二)-动态查询多表操作

    SpringDataJpa (二)-动态查询&多表操作 一.动态查询 1.Specifications动态查询 1.1 搭建测试环境 1.1.1 导入坐标 1.1.2 创建客户实体类 1.1. ...

最新文章

  1. 直播这把“开鱼刀”能否救蘑菇街于“扑街”?
  2. PyQt4编程之模态与非模态对话框(一)
  3. mysql 架构优化_Mysql 架构及优化之-查询性能优化
  4. python知识点总结全_【转】Python高级知识点总结
  5. 软考 计算机网络,软考-计算机网络总复习
  6. 随笔-jsp 利用jstl标签分页
  7. 单调栈解木板倒水问题
  8. c语言prog1已停止工作,1.在考生文件夹下,要求程序PROG.C的功能是.doc
  9. 批量生成变量及引用_R语言:data.table语句批量生成变量
  10. excel根据html生成表头c,excel表头的制作 怎样在Excel里面制作表头?
  11. PumpkinRaising靶机渗透
  12. 信息安全实习:实习一 古典加密算法 Swing图形化 (报告+详细代码)
  13. HttpCore和HttpClient
  14. RocketMQ事务消息
  15. 一周5G资讯 | 移动将与广电5G共建共享;诺基亚发布首款5G手机;铁塔今年5G投资170亿元...
  16. 创业者如何打动投资者——创业态度决定一切
  17. 语音和面部识别技术能帮助AI在情商上超越人类吗
  18. CAN通信标准帧和扩展帧(全网最透彻解答)
  19. MTK-如何解锁OEM
  20. [md5]批量对txt文件加密

热门文章

  1. 怎样和处在“叛逆”阶段的孩子交流沟通?
  2. 很多家长学历不高,无法辅导孩子的家庭作业怎么办?
  3. 有哪些皮一下就很开心的句子?
  4. 电商并没有给我们创造一个就业机会
  5. 赚钱的公式是资源加经营
  6. MATLAB图形插入标题
  7. LeetCode-删除中间节点
  8. 关于java中的位运算
  9. ssis sql_使用sp_help_revlogin和SSIS传输登录任务将SQL登录名传输到AG的辅助副本
  10. apexsql使用方法_使用ApexSQL审核执行SQL Server审核