Django-ORM之ManyToManyField的使用-多对多关系
表结构设计
多对多关系表创建外键,典型例子:书--作者--出版社,书与作者的关系就可以看作是多对多关系。
# 表结构设计
class Book(models.Model):
title = models.CharField(max_length=32)
pub = models.ForeignKey('Publisher', on_delete=models.CASCADE) #与出版社之间建立多对一外键
class Author(models.Model):
name = models.CharField(max_length=32)
books = models.ManyToManyField('Book') # 描述多对多的关系 不生成字段 生成关系表
数据迁移
如果是在新的app中进行功能的设计,可以使用 python manage.py makemigrations app(应用名) 进行数据的迁移,数据迁移完之后会生成三张表,这是情理之中的事,因为多对多关系的两张表要建立连接的时,需要借助第三张表来维护二者的关系,这里会自动生成第三张表,如图:


【新建测试表结构】
from django.db import models
# Create your models here.
class Publisher(models.Model):
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
def __str__(self):
return "<Publisher object: {} {}>".format(self.id, self.name)
class Author(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
phone = models.CharField(max_length=11)
def __str__(self):
return "<Author object: {} {}>".format(self.id, self.name)
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)
memo = models.TextField(null=True)
# 创建外键,关联publish
publisher = models.ForeignKey(to="Publisher",null=True, on_delete=models.CASCADE)
# 创建多对多关联author
author = models.ManyToManyField(to="Author")
def __str__(self):
return "<Book object: {} {} {} {}>".format(self.id, self.title,self.price,self.author)
新建表结构
基于对象的正向查询
book_obj = models.Book.objects.get(pk=1)
print(book_obj)
print(book_obj.title)
print(book_obj.author) # 关系管理对象,通过books可以得到两张表的关系,输出:app01.Book.None
print(book_obj.author.all()) # 所关联的所有对象,输出:<QuerySet [<Author: <Author object: 1 金老板>>, <Author: <Author object: 2 小哪吒>>]>
基于对象的反向查询
author_obj = models.Author.objects.get(pk=1)
print(author_obj)
print(author_obj.book_set)
print(author_obj.book_set.all())
print(author_obj.name)
基于字段的正向查询
# 查找作者叽喳写的书
book_obj = models.Book.objects.filter(author__name='叽喳')
print(book_obj)
print(book_obj.first().title)
基于字段的反向查询
# 查找《叽叽喳喳》的作者
author_obj = models.Author.objects.filter(book__title='叽叽喳喳')
print(author_obj)
关系管理对象的方法set、add、remove、clear
all 关联的所有的对象
author_obj = models.Author.objects.get(pk=1)
book_obj = models.Book.objects.get(pk=1)
print(author_obj.book_set.all())
print(book_obj.author.all())
set 设置多对多关系,两种方式,添加对象列表
author_obj.book_set.set([3,4]) # 这个作者写的哪些书
author_obj.book_set.set(models.Book.objects.filter(pk__in=[3,4]))
add 添加多对多关系,两种方式,直接添加关系对象就好
author_obj.book_set.add(3,4)
author_obj.book_set.add(*models.Book.objects.filter(pk__in=[3,4]))
remove 删除多对多关系,两种方式,直接移除关系对象
author_obj.book_set.remove(3,4)
author_obj.book_set.remove(*models.Book.objects.filter(pk__in=[3,4]))
clear 清空当前对象多对多关系
author_obj.book_set.clear()
关系管理对象的方法create
author_obj.book_set.create(title='叽叽喳喳的世界',publisher_id=2,price=99.9)
book_obj.author.creat(name='小提莫',age=23,phone='13822567070')
【配合HTML模板】
# 获取对应的一个或者多个book的id,注意当或去多个值时使用的时getlist
books = request.POST.getlist('books')
# 新建作者
author_obj = models.Author.objects.create(name=name) #第一个name是Author表的字段名
# 给作者和书籍绑定关系
author_obj.books.set(books) # 【id,id】自动把两者的信息进行匹配保存
删除对象
# 直接调用delete方法删除即可
pk = request.GET.get("pk") # 过的主键
obj = models.Auther.objects.filter(id=pk) # 通过主键获得整个对象
obj.delete() # 删除对象
这里删除对象之后,会直接把与之相关的外键关系删除,而不会删除关系对应的图书对象
自定义外键
自己手动创建
手动创建关系表,所有的信息维护也需要手动进行增删改查
class Book(models.Model):
title = models.CharField(max_length=32)
class Author(models.Model):
name = models.CharField(max_length=32)
class Book_Author(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
date = models.DateField()
自己创建 + ManyToManyField
手动创建关系表,再借用through函数绑定到关系表,关系信息的维护仍是手动
class Book(models.Model):
title = models.CharField(max_length=32)
class Author(models.Model):
name = models.CharField(max_length=32)
books = models.ManyToManyField(Book, through='Book_Author')
class Book_Author(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
date = models.DateField() # 添加关系
#方式一:
m1 = BookAuthor(author=author对象,book=book对象)
#方式二:
m2 = BookAuthor.objects,create(author=author对象,book=book对象)
Django-ORM之ManyToManyField的使用-多对多关系的更多相关文章
- django数据库操作-增删改查-多对多关系以及一对多(外键)关系
一.一对多(外键) 例子:一个作者对应多本书,一本书只有一个作者 model代码: class Person(models.Model); name = models.CharField('作者姓名' ...
- 转: django数据库操作-增删改查-多对多关系以及一对多(外键)关系
原文链接:http://blog.csdn.net/u010271717/article/details/22044415 一.一对多(外键) 例子:一个作者对应多本书,一本书只有一个作者 model ...
- Django框架之第六篇(模型层)--单表查询和必知必会13条、单表查询之双下划线、Django ORM常用字段和参数、关系字段
单表查询 补充一个知识点:在models.py建表是 create_time = models.DateField() 关键字参数: 1.auto_now:每次操作数据,都会自动刷新当前操作的时间 2 ...
- Django ORM 多表操作
目录 Django ORM 多表操作 表模型 表关系 创建模型 逆向到表模型 插入数据 ORM 添加数据(添加外键) 一对多(外键 ForeignKey) 一对一 (OneToOneFeild) 多对 ...
- django -- 多对多关系的实现
在django中表和表之间的多对多关系有两种实现方案: 方案一:直接使用django自动实现的多对多关系. 方案二:自己写连接表.然而告诉django在实现多对多关系时要使用的连接表. 一.方案一: ...
- Django ORM、一对一、一对多、多对多、详解
上篇博客也提到这些知识点,可能大家还是不太清楚,这篇博客为大家详细讲解ORM中的几个知识点 1.1首先我们先看一个小案例: #_*_coding:utf-8_*_ from django.db imp ...
- Django --ORM常用的字段和参数 多对多创建形式
1 ORM字段 AutoField int自增列,必须填入参数 primary_key=True.当model中如果没有自增列,则自动会创建一个列名为id的列. IntegerField 一个整数类型 ...
- django ORM模型表的一对多、多对多关系、万能双下划线查询
一.外键使用 在 MySQL 中,如果使用InnoDB引擎,则支持外键约束.(另一种常用的MyIsam引擎不支持外键) 定义外键的语法为fieldname=models.ForeignKey(to_c ...
- Django中多对多关系的orm表设计
作者的管理 1.设计表结构 出版社 书籍 作者 一个出版社出版多个书籍 1对多 书籍和作者的关系:一个作者写多本书,一本书可以是多个作者写.多对多 1)创建一张表,表中多对多的数据关系.使用 多对多 ...
随机推荐
- BZOJ 4032: [HEOI2015]最短不公共子串 (dp*3 + SAM)
转博客大法好 第4个子任务中,为什么只转移最近的一个位置,自己YY吧(多YY有益身体健康). #include <bits/stdc++.h> using namespace std; t ...
- linux中强大的编辑工具vim
先来个图镇贴 vim是一个模式编辑器.由三种主要模式比较常用: 1.命令(Normal)模式:默认模式,移动光标,剪切/粘贴文本 2.插入(Insert)或编辑模式:修改文本 3.扩展命令(exten ...
- MySQL错误:ERROR 1067 (42000): Invalid default value for 'timestamp_field'
数据库报错 ERROR 1067 (42000): Invalid default value for 'start_time' 是因为数据库的配置有问题: 可以看到 NO_ZERO_IN_DA ...
- The Cost of JavaScript --------引用
tl;dr: 想要保持页面的快速运行,你需要仅加载当前页面所需的 JavaScript 代码.优先考虑用户所需,之后运用代码分离懒加载其他内容. Is it happening - 在这个时期,你可以 ...
- keras默认配置
使用keras后,会在用户目录下生成.keras/keras.json文件,Windows下为:C:\Users\user\.keras\keras.json,Linux下为:~/.keras/ker ...
- c语言函数分析
1.vc6的相关使用 1)常用的快捷键 f7 ->编译 f5 ->运行 f9 ->断点 f10 ->单步执行 f11 ->单步执行,可进入函 ...
- CCPC-Wannafly & Comet OJ 夏季欢乐赛(2019)E
题面 这个题暴好啊,考了很多东西. 首先设f(x)为离终点还有x步要走的期望步数,我们可以发现 : 1.x>=k时,x可以转移到的点的下标都<x. 2.x<k时,则可能走回到x或者下 ...
- Trie树(c++实现)——转载自jihite的博客
Trie树(c++实现) 原理 先看个例子,存储字符串abc.ab.abm.abcde.pm可以利用以下方式存储 上边就是Trie树的基本原理:利用字串的公共前缀来节省存储空间,最大限度的减少无谓 ...
- Linux可变参数打印日志(二)
#include<stdio.h> #include<stdlib.h> #include<stdarg.h> #include<string.h> # ...
- Codeforces 474D Flowers(DP)
题目链接 非常简单的一道dp题,通过O(n)的预处理来使查询变为O(1). 主要的坑在于取模后的dp数组的前缀和再相减可能得到负数,导致无法得到某一区间和的取模. 解决方法:(a-b)%mo==(a% ...