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 ...
随机推荐
- 多线程执行sql报错处理
pymysql多线程访问数据库报错:Packet sequence number wrong - got 7 expected 2 原文:https://www.cnblogs.com/heiao10 ...
- Django 会议室预定
表结构分析: from django.db import models # Create your models here. from django.db import models from dja ...
- [LuoguP1462]通往奥格瑞玛的道路
题目链接 题意简述:现在有一个图,每经过一个点就会交钱,走一条路就会扣血.在血量>0的前提下,要从1走到n点,并且要求路径上交钱的最大值最小. 解题思路:首先最大值最小,我们选择二分.目前有两个 ...
- 002_基础电路_AD快捷键
AD快捷键设置 陆小果哥哥制作 1. F2----------------------------------------放置走线 a) b) 需设置,点中走线按住 ...
- Error Permission denied when running brew cleanup
Error Permission denied when running brew cleanup When I try to run `brew cleanup` I get: Warning: S ...
- am335x system upgrade kernel can(八)
1 Scope of Document This document describes can bus hardware design and can bus driver developm ...
- ERROR: `elasticsearch` directory is missing in the plugin zip
该问题出现在为elasticsearch安装中文分词器插件时 问题发生在插件和es版本不匹配~ 解决: es版本与插件版本对应齐 命令行安装 C:\Users\SeeClanUkyo>F:\el ...
- 通过 frp 实现群晖的 drive 远端同步
通过 frp 实现 drive 同步 其实其他的也类似, 只是指定 tcp 的端口不一致就可以. frp 实现的外网端口映射"肥肠"方便. 也推广下 frp 的地址 frp-git ...
- MySQL5.7 基础之二
设计范式: 第一范式:字段是原子性 第二范式:存在可用主键 第三范式:任何表都不应该有依赖于其它表非主键的字段 创建数据库.设计数据表 字段:字段名.数据类型.约束(通过键来实现,而键其实可以当做索引 ...
- 新建Class文件时,添加作者版权注释声明
以安装路径C盘为例,各版本路径如下: VS2015:C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\ItemTempla ...