多对多的三种方式:

  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. Maximal Square II

    Description Given a 2D binary matrix filled with 0's and 1's, find the largest square which diagonal ...

  2. 学习Spring-Data-Jpa(六)---spring-data-commons中的repository

    1.spring-data-commons项目 spring-data-commons项目是所有spring-data项目的核心,我们来看一下该项目下的repository包中的接口和注解. 2.Re ...

  3. [Kubernetes] Pod Health

    Kubernetes relies on Probes to determine the health of a Pod container. A Probe is a diagnostic perf ...

  4. h5页面滑动卡顿解决方法

    解决方式: 给滚动的元素加样式:-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling(允许独立的滚动区域和触摸回弹) 如果值为au ...

  5. UOJ310. 【UNR #2】黎明前的巧克力 [FWT]

    UOJ 思路 显然可以转化一下,变成统计异或起来等于0的集合个数,这样一个集合的贡献是\(2^{|S|}\). 考虑朴素的\(dp_{i,j}\)表示前\(i\)个数凑出了\(j\)的方案数,发现这其 ...

  6. SqrtTree学习笔记

    散步的时候yy区间最值的不同分块做法,发现单点修改\(O(\sqrt{n})\)查询\(O(1)\)的做法不是很会? 于是yy了一个奇怪做法,写出来看看. 考虑查询的时候两端的散点可以用前后缀最值查出 ...

  7. git revert 让提交不再害怕

    git revert 让提交不再害怕 使用了好多命令, 但对于 git revert 一直不敢怎么使用, 为什么呢? 因为 git merge 的存在. 每次 对于 git merge 的分支, 执行 ...

  8. BAT 批量执行SQL脚本

    需要在BAT的sqlcmd中设置数据库连接信息. https://files.cnblogs.com/files/gguozhenqian/BAT%E6%89%A7%E8%A1%8CSQL%E8%84 ...

  9. 03、CPU主频,和性能

    性能?时间的倒数 有两个指标:一个是响应时间或者叫执行时间:一个是吞吐率或者带宽,这两个就可以理解为办事的时间和办事的多少. 而 性能= 1/响应时间 CPU时钟:计算机的计时单位 程序的CPU执行时 ...

  10. windows下使用xortools

    xortool是一个多字节异或加密破解工具.作者只是适配了linux版,在Windows下使用会导致保存文件错误,因为Windows会把\n转成\r\n,加密和解密都乱了.而且命令还和readme不一 ...