Python - Django - ORM 多对多表结构的三种方式
多对多的三种方式:
- ORM 自动创建第三张表
- 自己创建第三张表, 利用外键分别关联作者和书,关联查询比较麻烦,因为没办法使用 ORM 提供的便利方法
- 自己创建第三张表,使用 ORM 的 ManyToManyFiled(),使用此种方式创建多对多表的时候,没有 add() remove() 等方法
适用方法:
- 如果第三张表没有额外的字段,就用第一种
- 如果第三张表有额外的字段,就用第三种或第一种
方法二:
models.py:
from django.db import models # 书
class Book(models.Model):
title = models.CharField(max_length=32)
publish_date = models.DateField(auto_now_add=True)
price = models.DecimalField(max_digits=5, decimal_places=2) def __str__(self):
return self.title # 作者
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField() def __str__(self):
return self.name # 手动创建作者和书籍关联的第三张表
# 此时在 ORM 层面,作者和书籍就没有多对多的关系了
class Author2Book(models.Model):
id = models.AutoField(primary_key=True)
author = models.ForeignKey(to="Author") # 作者 id
book = models.ForeignKey(to="Book") # 书籍 id
在数据库中添加数据
author 表:
book 表:
author2book 表:
多对多的操作:
orm.py:
import os if __name__ == '__main__':
# 加载 Django 项目的配置信息
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")
# 导入 Django,并启动 Django 项目
import django
django.setup() from app02 import models
# 多对多的查询
# 查询 id 是 2 的作者关联的书籍的 id
ret = models.Author2Book.objects.filter(author_id=2).values_list("book_id")
print(ret) ret = [i[0] for i in ret] # 得到关联的书籍的 id
# 通过书籍的 id 查询 id 是 2 的作者关联的书籍名
ret = models.Book.objects.filter(id__in=ret)
print(ret)
运行结果:
这里的 [i[0] for i in ret] 是为了取元组中的 id:2、3,然后通过 id:2、3 获取它们的书籍
方法三:
models.py:
from django.db import models # Create your models here. # 书
class Book(models.Model):
title = models.CharField(max_length=32)
publish_date = models.DateField(auto_now_add=True)
price = models.DecimalField(max_digits=5, decimal_places=2) def __str__(self):
return self.title # 作者
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
# 通过 through,through_fields 来指定使用创建的第三张表来构建多对多的关系
books = models.ManyToManyField(to="Book", through="Author2Book", through_fields=("author", "book",)) def __str__(self):
return self.name # 手动创建作者和书籍关联的第三张表
class Author2Book(models.Model):
id = models.AutoField(primary_key=True)
author = models.ForeignKey(to="Author") # 作者id
book = models.ForeignKey(to="Book") # 书籍 id class Meta:
unique_together = ("author", "book") # 建立唯一约束
在数据库中添加与 app02 一样的数据
多对多的操作
orm.py:
import os if __name__ == '__main__':
# 加载 Django 项目的配置信息
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite2.settings")
# 导入 Django,并启动 Django 项目
import django
django.setup() from app03 import models ret = models.Author.objects.get(id=2).books.all() # 获取 id 为 2 的作者关联的所有书籍
print(ret)
运行结果:
该方法中没有 remove() 方法,可以使用下面的方法:
models.Author2Book.objects.get(author_id=1, book_id=1).delete()
没有 django ORM 封装的那些快捷方法,我们要自己手动修改第三张表
Python - Django - ORM 多对多表结构的三种方式的更多相关文章
- Django创建多对多表关系的三种方式
方式一:全自动(不推荐) 优点:django orm会自动创建第三张表 缺点:只会创建两个表的关系字段,不会再额外添加字段,可扩展性差 class Book(models.Model): # ... ...
- 多表连接的三种方式 HASH MERGE NESTED
多表连接的三种方式详解 HASH JOIN MERGE JOIN NESTED LOOP------------------------------------------------------20 ...
- 多表连接的三种方式详解 hash join、merge join、 nested loop
在多表联合查询的时候,如果我们查看它的执行计划,就会发现里面有多表之间的连接方式.多表之间的连接有三种方式:Nested Loops,Hash Join 和 Sort Merge Join.具体适用哪 ...
- python 获取表单的三种方式
条件:urls.py文件中配置好url的访问路径.models.py文件中有Business表. 在views.py文件中实现的三种方式: from app01 improt models def b ...
- 示例讲解PostgreSQL表分区的三种方式
我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 简介 表分区是解决一些因单表过大引用的性能问题的方式,比如某张表过大就会造成查询变慢,可能分区是一种解决方案.一般建议 ...
- [python]django的mode设置表结构和serializers序列化数据
框架使用的库版本 python3.6.5 Django-2.0.6 djangorestframework-3.8.2 mysqlclient-1.3.12 1.项目结构声明,数据库在setting. ...
- 多表连接的三种方式详解 HASH JOIN MERGE JOIN NESTED LOOP
在多表联合查询的时候,如果我们查看它的执行计划,就会发现里面有多表之间的连接方式. 之前打算在sqlplus中用执行计划的,但是格式看起来有点乱,就用Toad 做了3个截图. 从3张图里我们看到了几点 ...
- form表单提交三种方式,demo实例详解
第一种:使用type=submit 可以直接提交 <html> <head> <title>submit直接提交</title> </head& ...
- Python - Django - ORM 多对多操作
models.py: from django.db import models # 出版社 class Publisher(models.Model): id = models.AutoField(p ...
随机推荐
- sentinel主从切换技术
主从切换技术的方法是: 当主服务器宕机后,需要手动把一台从服务器切换为主服务器, 这就需要人工干预,费事费力,还会造成一段时间内服务不可用. 这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式. 一 ...
- js 定时器 执行一次和重复执行
1- 执行一次(延时定时器) var t1 = window.setTimeout(function() { console.log('1秒钟之后执行了') },1000) window.clearT ...
- 洛谷 P2279 [HNOI2003]消防局的设立 题解
每日一题 day34 打卡 Analysis 这道题的正解本来是树形dp,但要设5个状态,太麻烦了.于是我就用贪心试图做出此题,没想到还真做出来了. 考虑当前深度最大的叶子结点,你肯定要有一个消防局去 ...
- Kafka ISR and AR HW 、 LEO
相信大家已经对 kafka 的基本概念已经有一定的了解了,下面直接来分析一下 ISR 和 AR 的概念. 0|1ISR and AR 简单来说,分区中的所有副本统称为 AR (Assigned Rep ...
- P1903 [国家集训队]数颜色 (带修改莫队)
题目描述 墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问.墨墨会向你发布如下指令: 1. Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔. 2 ...
- Spark设置自定义的InputFormat读取HDFS文件
本文通过MetaWeblog自动发布,原文及更新链接:https://extendswind.top/posts/technical/problem_spark_reading_hdfs_serial ...
- mac Understand 安装破解
下载:链接:https://pan.baidu.com/s/1UvxgFnjv9pRVJmZO-J2OrQ 密码:nyd4 启动后,开始激活,点击enter License code 点击“use ...
- 深度学习面试题07:sigmod交叉熵、softmax交叉熵
目录 sigmod交叉熵 Softmax转换 Softmax交叉熵 参考资料 sigmod交叉熵 Sigmod交叉熵实际就是我们所说的对数损失,它是针对二分类任务的损失函数,在神经网络中,一般输出层只 ...
- flask 设置访问地址 和 访问端口
app.run() 四个参数 host:主机,可设置为本地或其他IP port:端口,是run()启动服务的时候指定的运行端口, debug:调试,如果需要进入调试模式,可以将这个选项设置成True ...
- useEffect 实现 componentWillUnmount生命周期函数(四)
在写React应用的时候,在组件中经常用到componentWillUnmount生命周期函数(组件将要被卸载时执行).比如我们的定时器要清空,避免发生内存泄漏;比如登录状态要取消掉,避免下次进入信息 ...