Django框架表关系外键-多对多外键(增删改查)-正反向的概率-多表查询(子查询与联表查询)

2023-05-13,,

目录
一:表关系外键
1.提前创建表关系
2.目前只剩 书籍表和 书籍作者表没创建信息。
3.增
4.删
5.修改
二:多对多外键增删改查
1.给书籍绑定作者
2.删
3.修改
4.清空
三:正反向的概念
1.什么是正向?
2.什么是反向?
3.判断正向反向
4.查询方式
5.应用场景.all()
四:多表查询
1.子查询与联表查询
五:子查询(基于对象的跨表查询)
1.子查询(正向)
2.子查询(正向)总结
3.子查询(反向)
4.子查询(反向)
六:联表查询(基于双下划线的跨表查询)
1.values作用
2.filter作用
2.查询objk的手机号 (一行代码搞定)
3.查询书籍主键为1的出版社名和书的名称
4.查询书籍主键为1的作者姓名
5.查询书籍主键是1的作者的手机号
6.总结:双下划线的跨表查询

一:表关系外键

1.提前创建表关系
from django import models

# 书籍
class Book(models.Model):
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8,decimal_places=2)
publish_data = models.DateField(auto_now_add=True) # 一对多(出版社对书籍)
publish = models.ForeignKey(to='Publish') # 多对多
authors = models.ManyToManyField(to='Author') # 出版社
class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=64)
email = models.EmailField() # 该字段类型不是给models看的 而是给后面我们会学到的校验组件看的 # 作者
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField() # 一对一
author_detail = models.OneToOneField(to='AuthorDetail') # 作者详情
class AuthorDetail(models.Model):
phone = models.BigIntegerField() # 电话号码用BigIntegerField或者直接用CharField
addr = models.CharField(max_length=64)
2.目前只剩 书籍表和 书籍作者表没创建信息。

3.增
1.直接写实际字段 id
models.Book.objects.create(title='论语', price=899.23, publish_id=1) 2.虚拟字段 对象
出版社对象
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='红楼梦', price=666.23, publish=publish_obj)
4.删
models.Publish.objects.filter(pk=1).delete()  # 级联删除
5.修改
1.直接直接写实际字段 id
models.Book.objects.filter(pk=1).update(publish_id=2) 2.虚拟字段 对象
publish_obj = models.Publish.objects.filter(pk=1).first()
models.Book.objects.filter(pk=1).update(publish=publish_obj)

二:多对多外键增删改查

多对多 增删改查 就是在操作第三张关系表

1.给书籍绑定作者
书籍对象
book_obj = models.Book.objects.filter(pk=1).first()
print(book_obj.authors) # 点authors就类似于你已经到了第三张关系表了
书籍id为1的书籍绑定一个主键为1 的作者
book_obj.authors.add(1)
书籍id为1的书籍绑定一个主键为2 和 主键为3 的作者
book_obj.authors.add(2, 3) 支持外键 对象
author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=2).first()
author_obj2 = models.Author.objects.filter(pk=3).first()
书籍id为1的书籍绑定一个主键为1 的作者
book_obj.authors.add(author_obj)
book_obj.authors.add(author_obj1, author_obj2)
add给第三张关系表添加数据
括号内既可以传数字也可以传对象 并且都支持多个
2.删
书籍对象
book_obj = models.Book.objects.filter(pk=1).first()
书籍id为1删除 主键为2 的作者
book_obj.authors.remove(2) 支持作者对象
author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=3).first() 删除 书籍id为1 作者主键为1和3 的 作者
book_obj.authors.remove(author_obj, author_obj1)
remove
括号内既可以传数字也可以传对象 并且都支持多个
3.修改
书籍对象
book_obj = models.Book.objects.filter(pk=1).first()
将书籍id为1 关联的作者主键id修改成2
book_obj.authors.set([2]) # 括号内必须给一个可迭代对象
将书籍id为1 关联的作者主键id修改成 1 和 2
book_obj.authors.set([2, 3]) # 括号内必须给一个可迭代对象 支持作者对象
author_obj = models.Author.objects.filter(pk=1).first()
author_obj1 = models.Author.objects.filter(pk=3).first()
set
括号内必须传一个可迭代对象 该对象内既可以书籍也可以对象 并且都支持多个 1.先删除后新增
2.如果值存在 就不动
4.清空
书籍对象
book_obj = models.Book.objects.filter(pk=1).first()
在第三张关系表中清空某个书籍于作者的绑定关系
book_obj.authors.clear()
clear
括号内什么参数都不要加

三:正反向的概念

1.什么是正向?
外键字段在我手上那么,我查你就是正向
2.什么是反向?
外键字段如果不在手上,我查你就是反向
3.判断正向反向
book >>>外键字段在书那儿(正向)>>> publish
publish >>>外键字段在书那儿(反向)>>>book 一对一和多对多正反向的判断也是如此
4.查询方式
正向查询:
按外键字段 反向查询按:
表名小写加_set 当你的查询结果有多个的时候就需要加.all()
如果是一个则直接拿到数据对象
5.应用场景.all()
1.书籍只能对应一个出版社  不需要.all()

2.书籍可以有可以作者  需要.all()

3.作者只能有一个作者详细信息  不需要.all()

四:多表查询

1.子查询与联表查询
多表查询分为
子查询:
基于对象的跨表查询
联表查询:
基于双下划线的跨表查询

五:子查询(基于对象的跨表查询)

1.子查询(正向)
eg:子查询就是分布操作

1.查询书籍为1的出版社名称
获取书籍对象
book_obj = models.Book.objects.filter(pk=1).first()
书查出版社 正向 按照字段查询
res = book_obj.publish
print(res) # 对象:东方出版社
print(res.name) # 东方出版社
print(res.addr) # 东方 2.查询书籍主键为2的作者
book_obj = models.Book.objects.filter(pk=2).first()
书查作者 正向
res = book_obj.authors # app01.Author.None 当拿到的结果是该结果 没有错 只是少了一个all()
res = book_obj.authors.all()
拿到书籍两个作者 <QuerySet [<Author: Author object>, <Author: Author object>]>
print(res) 3.查询作者objk的电话号码
1.先获取作者对象
author_obj = models.Author.objects.filter(name='objk').first()
作者 查 作者详细信息
res = author_obj.author_detail
print(res) # 详情信息对象 AuthorDetail object
print(res.phone) # 110
2.子查询(正向)总结
在书写orm语句的时候跟写sql语句一样的
不要企图一次性将orm语句写完 如果比较复杂 就写一点看一点 正向什么时候需要加.all()
当你的结果可能有多个的时候就需要加.all()
如果是一个则直接拿到数据对象 应用场景: 1.书籍只能对应一个出版社 不需要.all()
book_obj.publish 2.书籍可以有可以作者 需要.all()
book_obj.authors.all() 3.作者只能有一个作者详细信息 不需要.all()
author_obj.author_detail
3.子查询(反向)
4.查询出版社是东方出版社出版的书
先查询出版社
publish_obj = models.Publish.objects.filter(name='东方出版社').first()
出版社查书 反向 表名小写_set
res = publish_obj.book_set # app01.Book.None 该情况使用all()
res = publish_obj.book_set.all() # <QuerySet [<Book: Book object>, <Book: Book object>, <Book: Book object>]>
print(res.title) 5.查询作者是objk写过的书
先获取作者对象
author_obj = models.Author.objects.filter(name='objk').first()
作者 查书籍 反向
res = author_obj.book_set.all()
print(res) # <QuerySet [<Book: Book object>]> 6.查询手机号是110的作者姓名
作者 查 作者详情 反向
先拿作者详情手机号为110对象
author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
res = author_detail_obj.author
print(res.name) # objk
4.子查询(反向)
基于对象
反向查询的时候
当你的查询结果可以有多个的时候 就必须加_set.all()
当你的结果只有一个的时候不需要加_set.all()

六:联表查询(基于双下划线的跨表查询)

基于双下划线的跨表查询

1.values作用
values可以放多个字段
1.既可以用单选表的字段
2.也可以用跨表查询的特点
3.利用正反向概率跨表,然后取字段
2.filter作用
filter同样支持正反向的概念
2.查询objk的手机号 (一行代码搞定)
# 正向查询 按照字段  author_detail跨表查询双下划线phone 取字段
res = models.Author.objects.filter(name='objk').values('author_detail__phone', 'nmae')
print(res)
# <QuerySet [{'author_detail__phone': 110}]>

反向

不许点author完成该题

# 反向  						拿作者姓名是objk的作者详情
res = models.AuthorDetail.objects.filter(author__name='objk').values('phone','author__name')
print(res)

3.查询书籍主键为1的出版社名和书的名称
res = models.Book.objects.filter(pk=1).values('title','publish__name')
print(res)
# <QuerySet [{'title': '三国演义', 'publish__name': '东方出版社'}]>

反向

res = models.Publish.objects.filter(book__id=1).values('name','book__title')
print(res)
# <QuerySet [{'name': '东方出版社', 'book__title': '三国演义'}]>
4.查询书籍主键为1的作者姓名
res = models.Book.objects.filter(pk=1).values('authors__name')
print(res)
# <QuerySet [{'authors__name': 'objk'}]>

反向

res = models.Author.objects.filter(book__id=1).values('name')
print(res)
# <QuerySet [{'name': 'objk'}]>
5.查询书籍主键是1的作者的手机号

需求:

该需求 涉及到 三张表 (book  author  author_detail)
# authors 作者表  authors__author_detail 作者详情表  authors__author_detail__phone  双下划线获取手机号字段
res = models.Book.objects.filter(pk=1).values('authors__author_detail__phone')
print(res)

6.总结:双下划线的跨表查询
你只要掌握了正反向的概念
以及双下划线
那么你就可以无限制的跨表

Django框架表关系外键-多对多外键(增删改查)-正反向的概率-多表查询(子查询与联表查询)的相关教程结束。

《Django框架表关系外键-多对多外键(增删改查)-正反向的概率-多表查询(子查询与联表查询).doc》

下载本文的Word格式文档,以方便收藏与打印。