作者的管理

1.设计表结构

出版社 书籍 作者

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

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

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

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

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

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

 

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})

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

打印查看各个变量的含义

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

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

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

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

外键和多对多关系区别:

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

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

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 %}

模板

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

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

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

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

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地址,一个函数,外加一个模板。每个功能都是这样

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

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

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

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

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

存入数据库:

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

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

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

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

如下演示:

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

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

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

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

删除操作逻辑如下:

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

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

删除成功;

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条件相等的作者表中关系管理对象的所有对象

逻辑关系如下:

# 编辑作者
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之前会把和这个对象在关联表中关联的删掉并重新创建

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

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

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

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

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表设计的更多相关文章

  1. Django 之多对多关系

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

  2. Django中的Object Relational Mapping(ORM)

    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程序(django数据库多对多关系)

    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. plsql 的三种循环

    set serveroutput on declare pnum ; begin loop dbms_output.put_line(pnum); pnum :; end loop; end; / s ...

  2. 【视频开发】 十全大补:CxImage图像处理类库

     十全大补:CxImage图像处理类库 转载IT168        CxImage是一个可以用于MFC 的C++图像处理类库类,它可以打开,保存,显示,转换各种常见格式的图像文件,比如BMP, JP ...

  3. 【视频开发】RTSP SERVER(基于live555)详细设计

    /* *本文基于LIVE555的嵌入式的RTSP流媒体服务器一个设计文档,个中细节现剖于此,有需者可参考指正,同时也方便后期自己查阅.(本版本是基于2011年的live555) 作者:llf_17@q ...

  4. python断点

    pycharm怎么debug单步调试 1.打开一个Pycharm的界面,需要选中编辑器中的左侧. 2.点击Run---->Debug运行 3.点击箭头,向下运行 4.可以看到代码运行到下一条 5 ...

  5. Apache Kafka工作流程| Kafka Pub-Sub Messaging

    1.目标 在我们上一篇Kafka教程中,我们讨论了Kafka Docker.今天,我们将讨论Kafka Workflow.此外,我们将详细介绍Pub-Sub Messaging的工作流程以及Queue ...

  6. MySQL 总结篇 [在Oracle基础上学习的MySQL]

    一.学习环境 MySQL 5.7社区版 Navicat for MySQL 百度网盘下载链接:https://pan.baidu.com/s/1yGnznwoZ8CaMgrCsDBhKAQ 二.MyS ...

  7. T-SQL行列相互转换命令:PIVOT和UNPIVOT使用详解

    最近在维护一个ERP 做二次开发 ,在查找数据源的时候看到前辈写的SQL ,自己能力有限 ,就在网上找找有关这几个关键字的使用方法.做出随笔以做学习之用 T-SQL语句中,PIVOT命令可以实现数据表 ...

  8. canal+kafka订阅Mysql binlog将数据异构到elasticsearch(或其他存储方式)

    canal本质就是"冒充"从库,通过订阅mysql bin-log来获取数据库的更改信息. mysql配置(my.cnf) mysql需要配置my.cnf开启bin-log日志并且 ...

  9. python MySQL 插入Elasticsearch

    一.需求分析 注意: 本环境使用 elasticsearch 7.0版本开发,切勿低于此版本 mysql 表结构 有一张表,记录的数据特别的多,需要将7天前的记录,插入到Elasticsearch中, ...

  10. Codeforces Round #569 Div. 1

    A:n-1次操作后最大值会被放到第一个,于是暴力模拟前n-1次,之后显然是循环的. #include<bits/stdc++.h> using namespace std; #define ...