表结构设计

多对多关系表创建外键,典型例子:书--作者--出版社,书与作者的关系就可以看作是多对多关系。

  1. # 表结构设计
  2. class Book(models.Model):
  3. title = models.CharField(max_length=32)
  4. pub = models.ForeignKey('Publisher', on_delete=models.CASCADE) #与出版社之间建立多对一外键

  5. class Author(models.Model):
  6. name = models.CharField(max_length=32)
  7. books = models.ManyToManyField('Book') # 描述多对多的关系 不生成字段 生成关系表

数据迁移

如果是在新的app中进行功能的设计,可以使用 python manage.py makemigrations app(应用名) 进行数据的迁移,数据迁移完之后会生成三张表,这是情理之中的事,因为多对多关系的两张表要建立连接的时,需要借助第三张表来维护二者的关系,这里会自动生成第三张表,如图:

【新建测试表结构】
  1. from django.db import models

  2. # Create your models here.
  3. class Publisher(models.Model):
  4. name = models.CharField(max_length=32)
  5. city = models.CharField(max_length=32)

  6. def __str__(self):
  7. return "<Publisher object: {} {}>".format(self.id, self.name)

  8. class Author(models.Model):
  9. name = models.CharField(max_length=32)
  10. age = models.IntegerField()
  11. phone = models.CharField(max_length=11)

  12. def __str__(self):
  13. return "<Author object: {} {}>".format(self.id, self.name)

  14. class Book(models.Model):
  15. title = models.CharField(max_length=32)
  16. publish_date = models.DateField(auto_now_add=True)
  17. price = models.DecimalField(max_digits=5, decimal_places=2)
  18. memo = models.TextField(null=True)
  19. # 创建外键,关联publish
  20. publisher = models.ForeignKey(to="Publisher",null=True, on_delete=models.CASCADE)
  21. # 创建多对多关联author
  22. author = models.ManyToManyField(to="Author")

  23. def __str__(self):
  24. return "<Book object: {} {} {} {}>".format(self.id, self.title,self.price,self.author)

新建表结构

基于对象的正向查询

  1. book_obj = models.Book.objects.get(pk=1)
  2. print(book_obj)
  3. print(book_obj.title)
  4. print(book_obj.author) # 关系管理对象,通过books可以得到两张表的关系,输出:app01.Book.None
  5. print(book_obj.author.all()) # 所关联的所有对象,输出:<QuerySet [<Author: <Author object: 1 金老板>>, <Author: <Author object: 2 小哪吒>>]>

基于对象的反向查询

  1. author_obj = models.Author.objects.get(pk=1)
  2. print(author_obj)
  3. print(author_obj.book_set)
  4. print(author_obj.book_set.all())
  5. print(author_obj.name)
基于字段的正向查询
  1. # 查找作者叽喳写的书
  2. book_obj = models.Book.objects.filter(author__name='叽喳')
  3. print(book_obj)
  4. print(book_obj.first().title)

基于字段的反向查询

  1. # 查找《叽叽喳喳》的作者
  2. author_obj = models.Author.objects.filter(book__title='叽叽喳喳')
  3. print(author_obj)

关系管理对象的方法set、add、remove、clear

all 关联的所有的对象

  1. author_obj = models.Author.objects.get(pk=1)
  2. book_obj = models.Book.objects.get(pk=1)
  3. print(author_obj.book_set.all())
  4. print(book_obj.author.all())

​set 设置多对多关系,两种方式,添加对象列表

  1. author_obj.book_set.set([3,4]) # 这个作者写的哪些书
  2. author_obj.book_set.set(models.Book.objects.filter(pk__in=[3,4]))

add 添加多对多关系,两种方式,直接添加关系对象就好

  1. author_obj.book_set.add(3,4)
  2. author_obj.book_set.add(*models.Book.objects.filter(pk__in=[3,4]))

remove 删除多对多关系,两种方式,直接移除关系对象

  1. author_obj.book_set.remove(3,4)
  2. author_obj.book_set.remove(*models.Book.objects.filter(pk__in=[3,4]))
  1. clear 清空当前对象多对多关系
  1. author_obj.book_set.clear()

关系管理对象的方法create

  1. author_obj.book_set.create(title='叽叽喳喳的世界',publisher_id=2,price=99.9)
  2. book_obj.author.creat(name='小提莫',age=23,phone='13822567070')

【配合HTML模板】

  1. # 获取对应的一个或者多个book的id,注意当或去多个值时使用的时getlist
  2. books = request.POST.getlist('books')

  3. # 新建作者
  4. author_obj = models.Author.objects.create(name=name) #第一个name是Author表的字段名

  5. # 给作者和书籍绑定关系
  6. author_obj.books.set(books) # 【id,id】自动把两者的信息进行匹配保存
删除对象
  1. # 直接调用delete方法删除即可

  2. pk = request.GET.get("pk") # 过的主键
  3. obj = models.Auther.objects.filter(id=pk) # 通过主键获得整个对象
  4. obj.delete() # 删除对象
  5. 这里删除对象之后,会直接把与之相关的外键关系删除,而不会删除关系对应的图书对象

自定义外键

自己手动创建

手动创建关系表,所有的信息维护也需要手动进行增删改查

  1. class Book(models.Model):
  2. title = models.CharField(max_length=32)

  3. class Author(models.Model):
  4. name = models.CharField(max_length=32)

  5. class Book_Author(models.Model):
  6. book = models.ForeignKey(Book, on_delete=models.CASCADE)
  7. author = models.ForeignKey(Author, on_delete=models.CASCADE)
  8. date = models.DateField()
自己创建 + ManyToManyField

手动创建关系表,再借用through函数绑定到关系表,关系信息的维护仍是手动

  1. class Book(models.Model):
  2. title = models.CharField(max_length=32)

  3. class Author(models.Model):
  4. name = models.CharField(max_length=32)
  5. books = models.ManyToManyField(Book, through='Book_Author')

  6. class Book_Author(models.Model):
  7. book = models.ForeignKey(Book, on_delete=models.CASCADE)
  8. author = models.ForeignKey(Author, on_delete=models.CASCADE)
  9. date = models.DateField()
  10.  
  11. # 添加关系
  12. #方式一:
  13. m1 = BookAuthor(author=author对象,book=book对象)

  14. #方式二:
  15. m2 = BookAuthor.objects,create(author=author对象,book=book对象)

Django-ORM之ManyToManyField的使用-多对多关系的更多相关文章

  1. django数据库操作-增删改查-多对多关系以及一对多(外键)关系

    一.一对多(外键) 例子:一个作者对应多本书,一本书只有一个作者 model代码: class Person(models.Model); name = models.CharField('作者姓名' ...

  2. 转: django数据库操作-增删改查-多对多关系以及一对多(外键)关系

    原文链接:http://blog.csdn.net/u010271717/article/details/22044415 一.一对多(外键) 例子:一个作者对应多本书,一本书只有一个作者 model ...

  3. Django框架之第六篇(模型层)--单表查询和必知必会13条、单表查询之双下划线、Django ORM常用字段和参数、关系字段

    单表查询 补充一个知识点:在models.py建表是 create_time = models.DateField() 关键字参数: 1.auto_now:每次操作数据,都会自动刷新当前操作的时间 2 ...

  4. Django ORM 多表操作

    目录 Django ORM 多表操作 表模型 表关系 创建模型 逆向到表模型 插入数据 ORM 添加数据(添加外键) 一对多(外键 ForeignKey) 一对一 (OneToOneFeild) 多对 ...

  5. django -- 多对多关系的实现

    在django中表和表之间的多对多关系有两种实现方案: 方案一:直接使用django自动实现的多对多关系. 方案二:自己写连接表.然而告诉django在实现多对多关系时要使用的连接表. 一.方案一: ...

  6. Django ORM、一对一、一对多、多对多、详解

    上篇博客也提到这些知识点,可能大家还是不太清楚,这篇博客为大家详细讲解ORM中的几个知识点 1.1首先我们先看一个小案例: #_*_coding:utf-8_*_ from django.db imp ...

  7. Django --ORM常用的字段和参数 多对多创建形式

    1 ORM字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列. IntegerField 一个整数类型 ...

  8. django ORM模型表的一对多、多对多关系、万能双下划线查询

    一.外键使用 在 MySQL 中,如果使用InnoDB引擎,则支持外键约束.(另一种常用的MyIsam引擎不支持外键) 定义外键的语法为fieldname=models.ForeignKey(to_c ...

  9. Django中多对多关系的orm表设计

    作者的管理 1.设计表结构 出版社 书籍 作者 一个出版社出版多个书籍  1对多 书籍和作者的关系:一个作者写多本书,一本书可以是多个作者写.多对多 1)创建一张表,表中多对多的数据关系.使用 多对多 ...

随机推荐

  1. HDU-3746-Cyclic nacklace(KMP, 循环节)

    链接: https://vjudge.net/problem/HDU-3746 题意: 第一题来啦. 现在给你一个字符串,请问在该字符串末尾最少添加多少个字符,可以让这个字符串获得重复循环序列. 思路 ...

  2. npm报错 This is probably not a problem with npm,there is likely additional logging output above可能的原因

    npm WARN Local package.json exists, but node_modules missing, did you mean to install? 解决方法: 输入npm i ...

  3. Python入门-2编程基本概念:03引用的本质-栈内存和堆内存-内存示意图

    引用 在Python中,变量也称为:对象的引用.因为,变量存储的就是对象的地址. 变量通过地址引用了“对象”. 变量位于:栈内存(压栈出栈等细节,后续再介绍). 对象位于:堆内存. Python是动态 ...

  4. 炫酷CSS3垂直时间轴特效

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. 【Andriod-AlertDialog控件】 弹出对话框AlertDialog用法

    Result: Code: import android.app.Activity; import android.app.AlertDialog; import android.content.Di ...

  6. Sublime Text 3 全程详细图文使用教程

    一. 前言 使用Sublime Text 也有几个年头了,版本也从2升级到3了,但犹如寒天饮冰水,冷暖尽自知.最初也是不知道从何下手,满世界地查找资料,但能查阅到的资料,苦于它们的零碎.片面,不够系统 ...

  7. 第六天-css基础(css定位)

    css定位   方位名称:  left  right  top  bottom   position:absolute 绝对定位(脱离标准流 div{ width:100px; height:100p ...

  8. Java中的基本数据类型和引用类型

    一.基本数据类型: byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0 short:短整型,在内存中占16位,即2个字节,取值范围-32768 ...

  9. 新版uni-app 在微信小工具调试遇到报错解决方案

    问题描述:我在运行到微信小程序是运行报错打不开微信小程序报错如下图 结局方案:将微信小程序安全设置开启如下图

  10. spring-jms,spring-boot-starter-activemq JmsTemplate 发送方式

    spring-jms,spring-boot-starter-activemq JmsTemplate 发送方式 背景: 原来我准备是setDefaultDestinationName 设置队列的名称 ...