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

时间:2022-04-25 10:17:48

作者的管理

1.设计表结构

出版社 书籍 作者

一个出版社出版多个书籍  1对多

书籍和作者的关系:一个作者写多本书,一本书可以是多个作者写。多对多

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

1)创建一张表,表中多对多的数据关系。使用 多对多字段的方法

2)创建的这个类,会创建两个表,app_加类名(开头变小写),app_这个类名_另一张表类名

3)这个类创建的表中没有多对多的字段,多对多的关系是以这张表表名加_id和另一张表表名加_id两个字段合成的新的表,id主键自动生成

4)一般多对多字段关联的是有外键的那张表。

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

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

 

2.展示含有多对多关系的作者表

2.1、设计url

url(r'^author_list/', views.author_list),

2.2、写函数

# 展示作者
for author in all_authors:
print(author)
print(author.pk)
print(author.name)
print(author.books,type(author.books)) # 关系管理对象
print(author.books.all(),type(author.books.all()))
print('*'*)
def author_list(request):
# 查询所有的作者
all_authors = models.Author.objects.all()
return render(request,'author_list.html',{'all_authors':all_authors})

点击这里可清空打印内容:

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

打印查看各个变量的含义

<class 'django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager'>  关系管理对象

通过关系管理对象.all()拿到所有关联的对象

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

由上可知:从作者表author.books.all()[0].title 获得了book表的书名,那么由author.books.all()[0].pub就能获得对应的一条出版社表的记录。从这张多对多关系的表中,获取到对应多对多关系另一张表的多条记录,又由此能获得另一张表的具有外键的对应的外键表记录,三表联系在一起了。

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

Book和Author多对多的关系。books是Author中你想要的对象跟Book关联的所有对象。books的作用是在Author和Book中创建一个中间的关系对象,放在第三张表中,再根据这个中间的关系来获取Book中关联的对象

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

外键和多对多关系区别:

外键是根据book.pub拿到的就是关联的外键对象(每行数据);而多对多是Auther.books直接拿到的是一个关系管理对象,关系管理对象.all()才能拿到所有关联对象(每行数据)。

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

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

一个错误:一个函数重定向到自己这个函数会出现递归现象,达到递归上限,报错重定向次数过多,因此当这个函数想要重新返回到自身页面的时候用render,转到其它页面用render或者重定向

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

2.3、写模板

{% for author in all_authors %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ author.pk }}</td>
<td>{{ author.name }}</td>
<td>
{% for book in author.books.all %}

{% if forloop.last %}
《{{ book.title }}》
{% else %}
《{{ book.title }}》、
{% endif %}

{% endfor %}
</td>

</tr>
{% endfor %}

模板

将对象列表循环出来再取需要的字段,并添加书名号。

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

将循环出来的每个内容用顿号隔开。

如果只是在后面加个逗号,那么最后那个都会显示逗号:

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

for循环中批量操作数据,通过添加判断实现满足条件的输出不同内容,

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

3.多对多关系表的数据增加

# 新增出版社
def add_publisher(request):
error = ''
# 对请求方式进行判断
if request.method == 'POST':
# 处理POST请求
# 获取到出版社的名称
publisher_name = request.POST.get('publisher_name')
# 判断出版社名称是否有重复的
if models.Publisher.objects.filter(name=publisher_name):
error = '出版社名称已存在'
# 判断输入的值是否为空
if not publisher_name:
error = '不能输入为空'
if not error:
# 使用ORM将数据插入到数据库中
obj = models.Publisher.objects.create(name=publisher_name)
# 跳转到展示出版社的页面
return redirect('/publisher_list/')
# 返回一个包含form表单的页面
return render(request, 'add_publisher.html', {'error': error})

新增逻辑和代码

author_obj = models.Author.objects.create(name=author_name) # 只插入book表中的内容
author_obj.books.set(books) # 设置作者和书籍多对多的关系

一个功能,一个url地址,一个函数,外加一个模板。每个功能都是这样

添加作者,选择作者写的多个书籍,提交。实现多选功能:

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

添加作者:将提交的作者名字和作品获取到并写入数据库,然后重定向到作者展示页面

如下:在页面选中多个提交,但是get获取book的值只获取到一个,应该是选择的book列表才是我们想要的,但是get只是获取到了最后一个数值

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

正确使用时getlist方法,获取select中多选的值

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

getlist获取到的类型是列表。多选中选中多个选项获取的值:

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

存入数据库:

1)先用input输入的作者名字创建作者表对象

2)再获取出来select选中多个关联选项

3)新建的作者对象.books获得关系管理对象,关系管理对象.set(要关联的多个外表的id列表)。由此,这个作者表对象set设置了和外表的多条记录的关系映射,并在第三张表中体现出来

【1】插入数据【2】设置它对多的关系

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

如下演示:

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

结果如下:表之接.东西,报错对象没有这个属性,这里是缺少objects了,直接表.create会把它当做表的字段看待

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

正确结果:,注意create不要将给多对多的代表关系管理对象的设置值

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

然后再设置重定向到book_list页面

4.多对多关系表的数据删除

删除操作逻辑如下:

拿到要删除的数据id,然后查表找到对应数据进行删除再返回到展示页面

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

url设置,写函数,作者展示首页添加删除按钮:

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

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

删除成功;

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

5.多对多关系表的数据修改

books = request.POST.getlist('books')

# 修改对象的数据
author_obj.name = name
author_obj.save()
# 多对多的关系
author_obj.books.set(books) # 每次重新设置

编辑和添加的html差不多,直接复制过来修改一下:

有多对多关系的表数据编辑:

1)url

2)函数

3)html

(1)作者展示页点击编辑a标签get请求并带有编辑的对象pk跳转到编辑页

(2)编辑页不是多对多关系的字段可以用输入框

(3)是多对多关系的需要使用多选框,多选框中是另一个表中所有作品,被选中的即已经是作者的作品  是与作者pk条件相等的作者表中关系管理对象的所有对象

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

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

逻辑关系如下:

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

# 编辑作者
def edit_author(request):
# 查询编辑的作者对象
pk = request.GET.get('pk')
author_obj = models.Author.objects.get(pk=pk) if request.method == 'POST':
# 获取提交的数据
name = request.POST.get('author_name')
books = request.POST.getlist('books') #注意是getlist,不然只能获取到一个数字
# 修改对象的数据
author_obj.name = name
author_obj.save()
# 多对多的关系
author_obj.books.set(books) # 每次重新设置 #不管是新增还是修改都使用set就行了
# 重定向
return redirect('/author_list/') # 查询所有的书籍
all_books = models.Book.objects.all() #请求方式判断在前,因为POST中用不到这个 return render(request, 'edit_author.html', {'author_obj': author_obj, 'all_books': all_books})

每次编辑都是重新设置,也就是set之前会把和这个对象在关联表中关联的删掉并重新创建

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

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

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

6.django设置多对多关系三种方法

1.django帮我们生成第三张表

class Author(models.Model):
name = models.CharField(max_length=)
books = models.ManyToManyField('Book') # 不在Author表中生产字段,生产第三张表

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

2.自己创建第三张表

class AuthorBook(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
book = models.ForeignKey(Book, on_delete=models.CASCADE)
date = models.DateField()

注销不用books

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

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

3.自建的表和 ManyToManyField 联合使用

class Author(models.Model):
name = models.CharField(max_length=)
books = models.ManyToManyField('Book',through='AuthorBook') # 不在Author表中生产字段,生产第三张表


class AuthorBook(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCA DE)
book = models.ForeignKey(Book, on_delete=models.CASCADE)
date = models.DateField()

1)第三种方式可以使用 ManyToManyField 方法,通过第一个字符串参数指定和哪个表关联;通过  through='自建第三张表'和自建第三张表联系起来,这样它本身不会创建第三张关联表了,而是以你写的第三张表的来作为它和它关联表之间的多对多关联关系。

2)这样的好处是我可以在django建立的关系表上添加字段(比如建立第三张关联表,图书id和作者id一一对应,但是我想要作者编写图书的时间,那么最好的地方就是放到这张表,而自建第三张表的方式才能给表添加字段;但是自建的表查询语句还要自己写,)

3)自建第三张表既能增加数据表字段,也能通过books.all()获取数据,但是不能使用set等某些方法,要想查数据还是要自己写语句

4)自建第三张表是自己设置另外两张表的外键字段

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

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


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

														
		

Django中多对多关系的orm表设计的更多相关文章

  1. Django 之多对多关系

    1. 多对多关系 作者 <--> 书籍 1. 表结构设计 1. SQL版 -- 创建作者表 create table author( id int primary key auto_inc ...

  2. Django中的Object Relational Mapping&lpar;ORM&rpar;

    ORM 介绍 ORM 概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说,ORM是通过使用 ...

  3. Django中三种方式写form表单

    除了在html中自己手写form表单外,django还可以通过 继承django.forms.Form 或django.forms.ModelForm两个类来自动生成form表单,下面依次利用三种方式 ...

  4. EF Codefirst 多对多关系 操作中间表的 增删改查(CRUD)

    前言 此文章只是为了给新手程序员,和经验不多的程序员,在学习ef和lambada表达式的过程中可能遇到的问题. 本次使用订单表和员工表建立多对多关系. 首先是订单表: public class Ord ...

  5. 关于hibernate中多对多关系

    关于多对多关系 数据库:在使用多对多的关系时,我们能够使用复合主键.也能够不使用,直接引入外键相同能够实现. 在数据库中使用多对多关系时,须要一个中间表. 多对多关系中的数据库结构例如以下: 表:Or ...

  6. Linux下开发python django程序&lpar;django数据库多对多关系&rpar;

    1.多对多关系数据访问 models.py设置 from django.db import models # Create your models here. sex_choices=( ('f',' ...

  7. XAF中多对多关系 (XPO)

    In this lesson, you will learn how to set relationships between business objects. For this purpose, ...

  8. django 的多对多关系

    django里自带的多对多表创建 其实就是两个多对一关系各自关联,在第三张表上 多对多的增加 add()可以传数值 例如 add(1)或数组 add(*[2,3]) 多对多反向操作 自己创建第三张表, ...

  9. Django中利用type动态操作数据库表

    场景分析: 后台MySql数据库保存了一大批按股票代码命名的数据表,每张表保存的是每只股票的日线数据. stock_000002 stock_600030 stock_600020 ...一共3000 ...

随机推荐

  1. 【Mysql】 局域网远程连接问题

    设置了 user 表 的 host为‘%’ 为什么局域网还是连接不上: 新建查询-->分别执行 1.GRANT ALL PRIVILEGES ON *.* TO'root'@'%' IDENTI ...

  2. sass安装记录

    之前曾经安装过一次sass,不过可惜没使用,现在换了电脑重新安装,又上网找了些资料,终于安装成功,现在就当做个记录方便下次安装. 首先 到官网下载个最新版的ruby :http://rubyinsta ...

  3. CentOS下安装Redis及Redis的PHP扩展

    1.安装Redis 1.1 如果没有安装wget,安装wget yum install wget 1.2 在http://redis.io/download页面查看redis版本,并下载安装 wget ...

  4. Win7 单机Spark和PySpark安装

    欢呼一下先.软件环境菜鸟的我终于把单机Spark 和 Pyspark 安装成功了.加油加油!!! 1. 安装方法参考: 已安装Pycharm 和 Intellij IDEA. win7 PySpark ...

  5. canvas基本用法

    1.canvas和其他标签一样使用,但是IE8以下是不支持的,可以在canvas里面加一个span用来提示,例如: <canvas> <span>IE8不支持canvas&lt ...

  6. BZOJ 1296 粉刷匠

    Description windy有\(N\)条木板需要被粉刷.每条木板被分为\(M\)个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. ...

  7. TravelCMS旅游网站系统前台诞生记-2(后台框架篇)

    经过一个多月的研发,前台页面已基本成型了,已开发了线路和签证两大模块,支持在线支付,微信支付待开发,在这个过程中,发现前端技术远比后台技术注重的细节多,特别是css,比我想象的要难,为了兼容各种浏览器 ...

  8. Material风格的Quick组件,妈妈再也不用担心我的界面不好看了

    https://github.com/papyros/qml-material http://www.zhihu.com/question/38523930

  9. DOM知识梳理

    DOM 我们知道,JavaScript是由ECMAScript + DOM + BOM组成的.ECMAScript是JS中的一些语法,而BOM主要是浏览器对象(window)对象的一些相关知识的集合. ...

  10. openssl req&lpar;生成证书请求和自建CA&rpar;

    伪命令req大致有3个功能:生成证书请求文件.验证证书请求文件和创建根CA.由于openssl req命令选项较多,所以先各举几个例子,再集中给出openssl req的选项说明.若已熟悉openss ...