Django多对多关系详解:自动建表、手动建表及级联删除

沈知远
沈知远
发布时间:2026-10-13| 6人浏览过
原创

本文详细介绍Django中多对多关系的实现方式。涵盖自动创建第三张关联表的机制与注意事项,包括处理已有数据时的迁移报错解决。同时演示如何手动创建第三张表并建立关联。内容包含通过add、remove、clear方法管理关联对象,以及级联删除对多对多关系的影响,提供完整的代码示例与操作步骤。

Django多对多关系基础与自动建表

首先创建Author作者模型,并在Book书籍模型中定义与Author的多对多关系。外键字段可以放置在任意一方,但在Django的多对多关系中,通常不需要显式定义外键,而是通过ManyToManyField隐式处理。


class Author(models.Model):

  name = models.CharField(max_length=32)

  #在Author表中创建第三张表,与book表创建多对多关系一样的效果

  # books = models.ManyToManyField(Book)

  #再重新生成数据库,因为新增了多对多关系,book表会新增字段,所以直接重新生成数据库就会报错,

在Book模型中关联Author模型时,如果Author模型定义在Book模型之前,可以直接引用Author类名。

若将Author作为字符串引用(即加上引号),Django会在加载完所有模型后再进行查询解析,此时Author模型可以在全局任何位置定义。

这种方式允许Author模型在Book模型之后定义,只要保证在应用加载结束时能解析到即可。

如果不加引号直接引用Author类,则必须确保Author模型在Book模型之前定义,否则会出现NameError。

在Book模型中,通过ManyToManyField字段创建与Author表的多对多关系。


class Book(models.Model):

  title = models.CharField(max_length=32)
  price = models.DecimalField(max_digits=5 , decimal_places=2)

  #书籍与出版社是一对多,书是多,出版社是一,外键(子表)建在多的表中,
  #publish 作为一个外键 与Book 表建立一对多关系,默认绑定到Book 的主键id上
  publish = models.ForeignKey(Publish,)

执行数据库迁移生成表结构时需注意:如果Book表中已存在数据,直接迁移会报错。因为Django会自动在Book表中新增一个author_id字段(用于存储关联关系),而原有数据没有该字段,导致不兼容。因此,在生成迁移前需先清空Book表中的数据。

执行以下命令生成并应用迁移:python manage.py makemigrations,然后python manage.py migrate。

迁移完成后,数据库中会自动生成一张名为book_author的第三张表。该表包含一个主键和两个外键(分别指向Book和Author),这是Django自动创建的关联表。此时即可开始添加书籍数据。

若需手动插入数据并绑定Book与Author的多对多关系,可以通过Django ORM进行操作。

在views视图函数中,先获取Book表中的一个book对象,通过book_obj.authors.all()查看该book关联的作者列表。

对于id=1的这本书,如果没有关联作者,返回None;如果有作者,则返回一个QuerySet对象集合,其中包含所有关联的作者对象。


#给第三张表添加关系,
  #看下authors对象

  book_obj = Book.objects.get(id=1)#获取一个书籍的对象,有可能是多个作者写的,是一个集合对象,

  #获取id=1 这本书的作者集合对象,类似列表结构
  print(book_obj.authors) #gu_orm.Author.None ,是id=1的这本书,没有作者,所以得到一个None,-----------------------------
  #如果给Book和author绑定了关系,添加值,就会得到一个Queryset集合,
  print(book_obj.authors.all())
  #< QuerySet[ < Author: egon >, < Author: alex >, < Author: yuan >] >---------------------------------------

---------------

多对多关系的代码实现与管理

方法1:通过获取单个对象来创建多对多关系,并逐一添加。

下面通过代码实现多对多关系的创建过程。

首先,建议删除原第三张表中的测试数据,以确保操作清晰。

步骤1:获取一个Book对象实例。


book_obj = Book.objects.get(id=1)#获取一个书籍的对象,有可能是多个作者写的,是一个集合对象,

步骤2:获取一个或多个Author对象实例。


 author1 = Author.objects.get(id=1)
 author2 = Author.objects.get(id=2)

步骤3:使用add方法将author1和author2添加到book_obj对象中。这将把这两个作者对象关联到该书。


#book表与author表绑定关系,把2个作者对象添加到,关联到Book对象
  book_obj.authors.add(author1,author2)

执行相关URL并刷新数据库,验证关联是否成功建立。

===

方法2:通过获取所有对象集合来创建多对多关系。注意使用*号将列表拆分为单个对象传入。


#先获取一个book对象,
book_obj = Book.objects.get(id=1)

#方法2 ,把所有的author加到book对象中
  author_list = Author.objects.all()
  book_obj.authors.add(*author_list)

=====

解除关联关系可使用clear()方法清除所有关联,或使用remove()方法删除指定的关联关系。


#解除关联关系
  book_obj.authors.clear()#解除了书与作者的所有关系,

  #指定删除Book与作者的关系,先获取要解除关联的对象,然后用remove的方法,
  author = Author.objects.get(name = 'alex')

  book_obj.authors.remove(author)

----

级联删除:当删除一个对象时,使用delete()方法,相关联的一对多和多对多关系也会被自动删除。

book_obj.delete()

----

手动创建第三张表与级联删除

ManyToManyField会自动生成第三张关联表,无需手动干预。

也可以手动创建第三张表来管理多对多关系,这提供了更多的灵活性。


#  manytomany,会自动生成第三张表,现在自己可以手动创建第3张表,

class book2author(models.Model):

  book = models.ForeignKey("Book")
  author = models.ForeignKey("Author")

手动创建后,数据库中会多出如book2author这样的表。

在views视图函数中,可以通过实例化手动创建的第三张表模型并调用save()方法来添加记录。


  #----给自己手动创建的第三张添加记录,实列化对象,用save保存
  b2a = book2author(book_id=2,author_id=1)#括号里面可以写集合,作者的集合对象,进行关联,
  b2a.save()
  return HttpResponse('ok')

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。