多对多的三种方式:

  1. ORM 自动创建第三张表
  2. 自己创建第三张表, 利用外键分别关联作者和书,关联查询比较麻烦,因为没办法使用 ORM 提供的便利方法
  3. 自己创建第三张表,使用 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 多对多表结构的三种方式的更多相关文章

  1. Django创建多对多表关系的三种方式

    方式一:全自动(不推荐) 优点:django orm会自动创建第三张表 缺点:只会创建两个表的关系字段,不会再额外添加字段,可扩展性差 class Book(models.Model): # ... ...

  2. 多表连接的三种方式 HASH MERGE NESTED

    多表连接的三种方式详解 HASH JOIN MERGE JOIN NESTED LOOP------------------------------------------------------20 ...

  3. 多表连接的三种方式详解 hash join、merge join、 nested loop

    在多表联合查询的时候,如果我们查看它的执行计划,就会发现里面有多表之间的连接方式.多表之间的连接有三种方式:Nested Loops,Hash Join 和 Sort Merge Join.具体适用哪 ...

  4. python 获取表单的三种方式

    条件:urls.py文件中配置好url的访问路径.models.py文件中有Business表. 在views.py文件中实现的三种方式: from app01 improt models def b ...

  5. 示例讲解PostgreSQL表分区的三种方式

    我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 简介 表分区是解决一些因单表过大引用的性能问题的方式,比如某张表过大就会造成查询变慢,可能分区是一种解决方案.一般建议 ...

  6. [python]django的mode设置表结构和serializers序列化数据

    框架使用的库版本 python3.6.5 Django-2.0.6 djangorestframework-3.8.2 mysqlclient-1.3.12 1.项目结构声明,数据库在setting. ...

  7. 多表连接的三种方式详解 HASH JOIN MERGE JOIN NESTED LOOP

    在多表联合查询的时候,如果我们查看它的执行计划,就会发现里面有多表之间的连接方式. 之前打算在sqlplus中用执行计划的,但是格式看起来有点乱,就用Toad 做了3个截图. 从3张图里我们看到了几点 ...

  8. form表单提交三种方式,demo实例详解

    第一种:使用type=submit  可以直接提交 <html> <head> <title>submit直接提交</title> </head& ...

  9. Python - Django - ORM 多对多操作

    models.py: from django.db import models # 出版社 class Publisher(models.Model): id = models.AutoField(p ...

随机推荐

  1. Samba服务安装

    安装Samba服务   1.在可以联网的机器上使用yum工具安装,如果未联网,则挂载系统光盘进行安装. # yum install samba samba-client samba-swat 有依赖关 ...

  2. 动手动脑-------找出指定文件夹下所有扩展名为.txt和.java的文件

    思路:首先向获取文件,如果是文件的话,则判断它是否以".txt"或".java"结尾,如果是则输出它的路径.如果是文件夹的话,则需获取子文件,利用递归方法遍历子 ...

  3. sql server 中的表值函数和标量值函数

      顾名思义:表值函数返回的是表,而标量值函数可以返回基类型 一.表值函数 用户定义表值函数返回 table 数据类型.对于内联表值函数,没有函数主体:表是单个 SELECT 语句的结果集. 以下示例 ...

  4. 洛谷 AT2434 JOI 公園 (JOI Park) 题解

    人生第一次AC黑题,我太感动了. 每日一题 day31 打卡 Analysis 先跑遍DJ,求出1到 i的最短路.得到每个点到 1号点的距离后,从小到大排序一遍,这时便可以枚举每个点到 1号点的距离修 ...

  5. 问题--Notepad++保存文件遇到Failed to save file

    一.问题如下 使用Notepad编码,保存时遇到问题:Failed to save file. Not enough space on disk to save file? 如下图所示: 二.解决方法 ...

  6. 83: 模拟赛 树形dp

    $des$ $sol$ 维护每个点的子树中的信息以及非子树的信息 $code$ #include <bits/stdc++.h> using namespace std; #define ...

  7. P1902 刺杀大使

    题目描述 伊朗伊斯兰革命卫队(某恐怖组织)正在策划一起刺杀行动,他们的目标是沙特驻美大 使朱拜尔.他们来到了沙特驻美使馆,准备完成此次刺杀,要进入使馆首先必须通过使馆前 的防御迷阵. 迷阵由 n*m ...

  8. (31)Vue安装

    在使用Vue的时候,推荐安装Vue Devtools https://github.com/vuejs/vue-devtools#vue-devtools Browser devtools exten ...

  9. 二扩域(GF(2^m))中的逆矩阵

    通常的逆矩阵可以用高斯消去法计算.十分有效.还可以使用LU分解,QR分解等. 二扩域中的逆矩阵则不同.看似简单,其实有别:它的所有元素定义在GF(2^m)中.从理论来看,似乎也可以用高斯消去法,只是计 ...

  10. Spring的xml中引入其他文件

    引入db.properties <!--加载db.properties文件--> <context:property-placeholder location="class ...