创建关联表

关于表关系的几个结论

(1)一旦确立表关系是一对多:建立一对多关系————在多对应的表中创建关联字段。
(2)一旦确立表关系是多对多:建立多对多关系————创建第三张关系表————id和两个关联字段。
(3)一旦确定表关系是一对一:建立一对一关系————在两张表的任意一张表中建立关联字段+Unique。
(4)其实上面说的“关联字段”就是外键——foreign key。

本文用到的表、字段及相互关系

(1)作者模型:一个作者有姓名和年龄。
(2)作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息:作者详情模型和作者模型之间是一对一的关系(one-to-one)
(3)出版社模型:出版社有名称,所在城市以及email。
(4)书籍模型: 书籍有书名和出版日期.一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);另外一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many)
(5)书跟作者是多对多关系,利用Django的建表语句我们可以新生成一张“关系表”——book2author

建表过程

models.py文件中的内容如下:
from django.db import models

#出版社
class Publish(models.Model):
#主键
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=55)
city = models.CharField(max_length=55)
#email有特定的格式!
email = models.EmailField() #作者详细
class AuthorDetail(models.Model):
nid = models.AutoField(primary_key=True)
#日期的格式
birthday = models.DateField()
#手机号
telephone = models.BigIntegerField()
addr = models.CharField(max_length=55) #作者表
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=55)
#年龄,int类型的小数字就可以
age = models.IntegerField()
#由于作者与作者详细表是一对一的关系:所以选择在作者表中这样建立外键
#注意这里还是只写authordetail就可以了,_id 程序会自动给加的!
#注意这里on_delete一定要加!而且to后面的表的名字要习惯性的加上1
#一对一!
authordetail = models.OneToOneField(to='AuthorDetail',to_field='nid',on_delete=models.CASCADE) #书籍
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=55)
#出版日期,日期格式
pub_date = models.DateField()
#价格,最大位数5位,小数后保留两位
price = models.DecimalField(max_digits=5,decimal_places=2)
#与出版社表关联的字段——publish_id
#注意自己写的时候只写publish就可以了!Django会自动补上_id
#注意:on_delete必须要加上!!!而且to后面的表的名字要习惯性的加上1
#注意 null=true表示允许为空值
# 一对多!
publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE,null=True)
#书跟作者是多对多的关系。理论上需要新建一张关系表。
#但是利用Django下面的语句既可以新建一张表,又可以分别将其与书籍表与作者表关联起来!
#多对多!
authors = models.ManyToManyField(to='Author')
'''
create table book2author(
id int primary_key auto_increment,
book_id int,
author_id int,
foreign_key (book_id) references Book(id),
foreign_key (author_id) references Author(id),
);
'''
接着,我们在terminal中运行:
python manage.py makemigrations
python manage.py migrate
效果如下:



最后我们在数据库中可以看到生成了5张表(建议大家用Navicat工具):

注意事项:
(1)表的名称myapp_modelName,是根据 模型中的元数据自动生成的,也可以覆写为别的名称
(2)id字段是自动添加的
(3)对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
(4)这个例子中的CREATE TABLE SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。
(5)定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加models.py所在应用的名称。
(6)外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None

添加表记录

为了方便,建议大家事先在publish、author、authordetail表中加几条数据。

一对多关系添加记录:

在book表中新增一条记录,由于publish表与book表是一对多的关系,关联字段为publish_id,因此我们先得找到对应的出版社,这里有两种方法:
方法一:
publish_obj = Publish.objects.get(nid=1)
Book.objects.create(title='三国',price=100,pub_date='1922-2-3',publish=publish_obj)
方法二:
Book.objects.create(title='三国',price=100,pub_date='1922-2-3',publish_id=1)
注意理解这里的publish_obj
一个简单的查询:查看水浒传书籍的出版社对应的邮箱——
book_boj = Book.objects.filter(title='水浒传').first()
ret = book_obj.publish.email
print(ret)

多对多关系添加记录

书籍与作者是多对多的关系。创建一个book记录,将两个作者关联到这个记录中,表示这两个作者写同一本书。
##注意这里的first()
book_obj = Book.objects.create(title='三国群英传2',price=200,pub_date='1900-3-4',publish_id=2)
whw = Author.objects.filter(nid=1).first()
www = Author.objects.filter(nid=2).first()
##绑定多对多关系的API。
##这个authors就是Book类里建多对多关系的时候的那个:authors = models.ManyToManyField(to='Author')
book_obj.authors.add(whw,www)

解除多对多关系

##解除多对多关系,注意first得加
book = Book.objects.filter(nid=4).first()
##注意这里的2代表author_id
book.authors.remove(2)
##也可以移除所有的关系:
book.authors.clear()

all()方法:

all()方法是这里一个比较重要的API,我们如果想得到某一本书所有的作者对象的集合可以这样做:
book = Book.objects.filter(nid=1).first()
ret = book.authors.all()
print(ret)
注意这里得出的ret是一个QuerySet对象,是与这本书关联的所有作者对象的集合
如果我们想查询主键为4的书籍的所有作者的名字,可以这样做:
book_obj = Book.objects.filter(nid=4).first()
rets = book_obj.authors.all().values('name')
print(rets)
得到的结果是:<QuerySet [{'name': 'whw'}, {'name': 'www'}]>
最后需要提醒大家一点:
本文略去了项目创建以及文件配置的过程,如需查看这部分内容,请大家看一下我上一篇文章https://www.cnblogs.com/paulwhw/p/9395085.html

ORM多表操作之创建关联表及添加表记录的更多相关文章

  1. 09 ORM 多表操作,创建表,添加记录

    1.数据库表关系 1.一对多 为什么需要,重复字段太多 一对多关系表 Book id title price publish_id 1 python 100 1 2 php 200 2 3 go 10 ...

  2. {django模型层(二)多表操作}一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询、分组查询、F查询和Q查询

    Django基础五之django模型层(二)多表操作 本节目录 一 创建模型 二 添加表记录 三 基于对象的跨表查询 四 基于双下划线的跨表查询 五 聚合查询.分组查询.F查询和Q查询 六 xxx 七 ...

  3. Oracle.数据的增删改、表操作(创建,修改,删除)、数据类型

    SELECT ename,dname FROM emp,dept WHERE emp.deptno=dept.deptno; SELECT dname,loc FROM dept; SELECT JO ...

  4. mysql一张表多个字段关联另一张表查询

    如下:一张订单表多个字段关联用户表: 1.链表查询 SELECT cu.id AS 'id',cu.version AS 'version',cu.cid AS 'cid',cu.uid AS 'ui ...

  5. Django ORM多表操作

    多表操作 创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对 ...

  6. 2019年6月14日 Web框架之Django_07 进阶操作(MTV与MVC、多对多表三种创建方式、前后端传输数据编码格式contentType、ajax、自定义分页器)

    摘要 MTV与MVC 多对多表三种创建方式 ajax ,前后端传输数据编码格式contentType 批量插入数据和自定义分页器 一.MVC与MTV MVC(Model View Controller ...

  7. SQL语句汇总(一)——数据库与表的操作以及创建约束

    首先,非常感谢大家对上篇博文的支持,真是让本菜受宠若惊,同时对拖了这么久才出了此篇表示抱歉. 前言:此文旨在汇总从建立数据库到联接查询等绝大部分SQL语句.SQL语句虽不能说很多,但稍有时间不写就容易 ...

  8. SQL语句汇总(一)——数据库与表的操作以及创建约束

    首先,非常感谢大家对上篇博文的支持,真是让本菜受宠若惊,同时对拖了这么久才出了此篇表示抱歉. 前言:此文旨在汇总从建立数据库到联接查询等绝大部分SQL语句.SQL语句虽不能说很多,但稍有时间不写就容易 ...

  9. ORM多表操作上

    一.创建模型 例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对一(on ...

随机推荐

  1. POJ1417 True Liars

    题意 Language:Default True Liars Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 6392 Accep ...

  2. spark aggregate函数详解

    aggregate算是spark中比较常用的一个函数,理解起来会比较费劲一些,现在通过几个详细的例子带大家来着重理解一下aggregate的用法. 1.先看看aggregate的函数签名在spark的 ...

  3. day 49 html 学习 css 学习

    画圆 <style> div{width: 100px; height:100px; border: solid red 3px; /*当弧度为.圆角半径为30时 得到的图像*/ bord ...

  4. jenkins 使用smtp2http 邮件服务,扩展灵活的构建通知功能

    smtp2http 是一个很方便的可以将smtp 转换为http 服务的工具,同时也支持扩展的开发,我们可以使用此工具 扩展灵活的ci.cd 生命周期管理,而不是简单的邮件处理 备注: 使用docke ...

  5. script标签的同步和异步

    1).把<script>标签放在<head>中意味着必须等到全部的js代码都下载解析和执行完成以后,才开始展现页面内容,为避免这个问题一般把js代码全部放在<body&g ...

  6. nginx下js文件修改后访问不更新问题解决

    今天遇到一个问题,nginx下js修改后不更新,加版本号,刷新浏览器缓存都不行,重启服务器才行,修改后又不更新了而且加载的js文件会有乱码或者文件加载不全的问题. 解决办法:修改nginx.conf, ...

  7. 文件权限控制--umask

    问题 有一个场景,在A机器上有一个可执行文件,将其压缩,然后拷贝到B机器上,解压,发现原来文件的可执行权限消失了. 原因 B机器上,当前解压用户的umask设置,限制了新创建文件的权限. umask是 ...

  8. Flume 拦截器(interceptor)详解

    flume 拦截器(interceptor)1.flume拦截器介绍拦截器是简单的插件式组件,设置在source和channel之间.source接收到的事件event,在写入channel之前,拦截 ...

  9. 转---CentOS安装Oracle数据库详细介绍及常见问题汇总

    一.安装前准备 1.软件硬件要求 操作系统:CentOS 6.4(32bit)Oracle数据库版本:Oracle 10g(10201_database_linux32.zip)最小内存:1G(检查命 ...

  10. 【巷子】---middleware---redux-promise-middleware---【react】

    一.Middleware的由来 单一的state是存储在store中,当要对state进行更新的时候,首先要发起一个action(通过dispatch函数),action的作用就是相当于一个消息通知, ...