09 ORM 多表操作,创建表,添加记录
1、数据库表关系
1.一对多
为什么需要,重复字段太多
一对多关系表
Book
id title price publish_id
1 python 100 1
2 php 200 2
3 go 100 1
4 java 300 1 Publish
id name email addr
1 人民出版社 123@qq.com 北京
2 南京出版社 456@qq.com 南京 #总结:一旦确定表关系是一对多:在多对应的表中创建关联字段,publish_id #查询python这本书的出版社的邮箱(子查询)
select Publish.email from Publish where Publish.id = ()
select Book.publish_id from Book where Book.title='python'
2.多对多
Book
id title price publish_id
1 python 100 1
2 php 200 2
3 go 100 1
4 java 300 1 Author
id name age addr
1 alex 34 beijing
2 jack 33 nanjing Book2Author
id book_id author_id
1 2 1
2 2 2
3 3 2 # 总结:一旦确定表关系是多对多:创建第三张表
Book2Author
id book_id author_id # alex出版过的书籍名称(子查询)
select Book.title from Book where Book.id in ()
select Book2Author.book_id where author_id = ()
select Author.id from Author where Author.name='alex'
3.一对一
Author
id name age ad_id(unique) id addr gender tel gf_name
1 alex 34 1 1 beijing male 110 小花
2 jack 33 2 2 nanjing female 999 红娘 # 为了解耦 #方式1:
Author
id name age ad_id(unique)
1 alex 34 1
2 jack 33 2 AuthorDetail
id addr gender tel gf_name
1 beijing male 110 小花
2 nanjing female 999 红娘 #方式2:
Author
id name age
1 alex 34
2 jack 33 AuthorDetail
id addr gender tel gf_name author_id(unique)
1 beijing male 110 小花 1
2 nanjing female 999 红娘 2 #总结:一旦确定关系为一对一:在两张表中的任意一张表中建立关联字段+Unique
2、sql语句创建关联表
Publish
Book
Author
Book2Author
AuthorDetail
create table publish(
id int primary key auto_increament,
name varchar(20)
); create table book(
id int primary key auto_increament,
title varchar(20),
price decimal(8,2),
pub_date date,
publish_id int,
foreign key(publish_id) references publish(id)
); create table authordetail(
id int primary key auto_increament,
tel varchar(20),
); create table author(
id int primary key auto_increament,
name varchar(20),
age int,
authordetail_id int unique,
foreign key(authordetail_id) references authordetail(id)
);
create table Book2Author(
id int primary key auto_increament,
book_id int,
author_id int,
foreign key(book_id) references book(id),
foreign key(author_id) references author(id)
);
3、ORM生成关联表模型
一对一
"""
1对1 author
create table author(
id int primary key auto_increament,
name varchar(20),
age int,
authordetail_id int unique,
foreign key(authordetail_id) references authordetail(id)
);
create table authordetail(
id int primary key auto_increament,
tel varchar(20),
);
""" # 作者表
class Author(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
age = models.IntegerField() # 1对1
# authordeatil = models.OneToOneField(to=AuthorDetail, to_field=nid) # 如果AuthorDetail表在后面定义也可以找到
# authordeatil = models.OneToOneField(to="AuthorDetail", to_field="nid") # 推荐使用字符串格式, # django2.0 会报错,级联删除
authordeatil = models.OneToOneField(to="AuthorDetail", to_field="nid", on_delete=models.CASCADE) # 作者详情表
class AuthorDetail(models.Model):
nid = models.AutoField(primary_key=True)
birthday = models.DateField()
telephone = models.BigIntegerField()
addr = models.CharField(max_length=32)
一对多、多对多
"""
一对多 Book -- Publish
create table publish(
id int primary key auto_increament,
name varchar(20)
); create table book(
id int primary key auto_increament,
title varchar(20),
price decimal(8,2),
pub_date date,
publish_id int,
foreign key(publish_id) references publish(id)
);
"""
# 出版社表
class Publish(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
city = models.CharField(max_length=32)
email = models.EmailField() # 书籍表
class Book(models.Model):
nid = models.AutoField(primary_key=True)
title = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
publishDate = models.DateField() # 1对多关系
# publish = models.ForeignKey(to=Publish, to_field='nid') # django2.0 会报错,级联删除
publish = models.ForeignKey(to=Publish, to_field='nid', on_delete=models.CASCADE) # 多对多
authors = models.ManyToManyField(to="Author") # manytomany不会报错级联删除
"""
多对多 Book---- Book2Author ---- Author create table Book2Author(
id int primary key auto_increament,
book_id int,
author_id int,
foreign key(book_id) references book(id),
foreign key(author_id) references author(id)
);
"""
多对多可以 继续定义Book2Author, 推荐使用ORM的 ManyToManyField
4、生成数据库表
级联删除错误
C:\PycharmProjects\ORM2>python manage.py makemigrations
Traceback (most recent call last):
File "manage.py", line 15, in <module>
execute_from_command_line(sys.argv)
File "C:\PycharmProjects\ORM2\app01\models.py", line 72, in <module>
class Author(models.Model):
File "C:\PycharmProjects\ORM2\app01\models.py", line 79, in Author
authordeatil = models.OneToOneField(to="AuthorDetail", to_field="nid")
TypeError: __init__() missing 1 required positional argument: 'on_delete'
# 级联删除字段 on_delete=models.CASCADE 一对多 一对一
publish = models.ForeignKey(to=Publish, to_field='nid', on_delete=models.CASCADE)
authordeatil = models.OneToOneField(to="AuthorDetail", to_field="nid", on_delete=models.CASCADE)
# authors = models.ManyToManyField(to="Author") 多对多 不会报错
python manage.py makemigrations
python manage.py migrate
注意事项:
- 表的名称
myapp_modelName
,是根据 模型中的元数据自动生成的,也可以覆写为别的名称 id
字段是自动添加的- 对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
- 这个例子中的
CREATE TABLE
SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。 - 定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加
models.py
所在应用的名称。 - 外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。
5、多表操作 添加记录
url
from django.contrib import admin
from django.urls import path, re_path, include urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'^app01/', include(('app01.urls', 'app01')))
]
from django.urls import path, re_path, include from app01 import views
urlpatterns = [
re_path(r'^add/$', views.add, name='add')
]
1.单表
from django.shortcuts import render,HttpResponse # Create your views here.
from app01.models import * def add(request):
# 1.单表添加记录
ret1 = Publish.objects.create(
name='人民出版社',
city='beijing',
email='123@qq.com',
)
ret2 = Publish.objects.create(
name='南京出版社',
city='nanjing',
email='456@qq.com',
)
print(ret2) # Publish object (2) return HttpResponse('OK')
2.一对多,一对一
绑定一对多的关系
方式1 方式2都有对象产生
(1) 方式1
# 方式1
# 为book表绑定出版社
book_obj = Book.objects.create(
title='西游记',
price=100,
publishDate="2012-11-11",
publish_id=1,
)
print(book_obj) # 西游记
print(book_obj.title) # 西游记
print(book_obj.price) #
print(book_obj.publishDate) # 2012-11-11
print(book_obj.publish) # Publish object (1)
print(book_obj.publish_id) #
(2) 方式2
# 方式2
# publish_obj = Publish.objects.filter(id=2).first() # 没有id属性
publish_obj = Publish.objects.filter(nid=2).first() # 先查找publish_obj 对象 book_obj = Book.objects.create(
title='红楼梦',
price=200,
publishDate="2012-11-11",
publish=publish_obj,
)
print(book_obj.title)
print(book_obj.price)
print(book_obj.publishDate)
print(book_obj.publish) # 与这本书关联的出版社对象
print(book_obj.publish.email) # 出版社对象,可以继续点方法
print(book_obj.publish_id)
(3)查询
# 查询红楼梦的出版社对应的邮箱
book_obj = Book.objects.filter(title='红楼梦').first()
print(book_obj.publish.email) # 456@qq.com
(4)一对一
author_obj = Author.objects.create(
name='alex',
age=22,
authordetail_id=1,
)
author_obj = Author.objects.create(
name='jack',
age=23,
authordetail_id=2,
)
3、多对多
(1)绑定多对多关系
# 3.绑定多对多的关系
book_obj = Book.objects.create(
title="大话设计模式",
price=200,
publishDate="2018-12-12",
publish_id=1,
) alex = Author.objects.get(name='alex')
jack = Author.objects.get(name='jack') # 绑定多对多关系的API
book_obj.authors.add(alex, jack)
# book_obj.authors.add(1, 2, 3) # eroor?
book_obj.authors.add(*[1, 2, 3]) # 推荐
id_li = [1,2,3]
book_obj.authors.add(*id_li)
(2)解除多对多关系
# 4.解除多对多关系
book_obj = Book.objects.filter(nid=4).first()
book_obj.authors.remove(2)
book_obj.authors.remove(*[1,2])
book_obj.authors.clear()
(3)多对多查询
# 查询主键为4的书籍的所有作者的名字
print(book_obj.authors.all()) # [obj1,obj2,...] querySet # 与这本书关联的所有作者对象集合
# <QuerySet [<Author: Author object (1)>]>
ret = book_obj.authors.all().values('name')
print(ret) # <QuerySet [{'name': 'alex'}]>
4、bulk_create多对多,添加
data
{
"alarm_info_id":797,
"notifier_data":[
{"id": 2191, "channel": ""},
{"id": 2392, "channel": ""}
]
}
实现
def record_notifier_channel(self, request, *args, **kwargs):
"""记录告警人和告警渠道"""
# 根据alarm_info_id和告警人id,create记录
alarm_info_id = request.data.get('alarm_info_id')
notifier_data = request.data.get('notifier_data')
if not alarm_info_id:
return self.render_to_json_response(status=1, msg='请输入alarm_info_id') # 取出数据
alarm_notifier_info_list = []
for notifier in notifier_data:
alarm_notifier_info_list.append(AlarmInfoCustomerChannel(
alarm_info=self.get_queryset().filter(id=alarm_info_id).first(),
notifier=CustomUser.objects.filter(id=notifier.get('id')).first(),
channel=notifier.get('channel')))
# 批量插入
try:
AlarmInfoCustomerChannel.objects.bulk_create(alarm_notifier_info_list)
return self.render_to_json_response(status=0, msg='记录成功')
except Exception as e:
return self.render_to_json_response(status=1, msg='记录失败%s' % str(e))
表结构
class AlarmInfoCustomerChannel(BaseModel):
"""某告警事件的告警用户和告警渠道"""
alarm_info = models.ForeignKey(AlarmInfo, verbose_name='告警事件', on_delete=models.CASCADE)
notifier = models.ForeignKey(CustomUser, verbose_name='告警通知用户', on_delete=models.SET_NULL, null=True)
channel = models.CharField(verbose_name="通知渠道", max_length=3, null=True, blank=True)
09 ORM 多表操作,创建表,添加记录的更多相关文章
- 第三百零六节,Django框架,models.py模块,数据库操作——创建表、数据类型、索引、admin后台,补充Django目录说明以及全局配置文件配置
Django框架,models.py模块,数据库操作——创建表.数据类型.索引.admin后台,补充Django目录说明以及全局配置文件配置 数据库配置 django默认支持sqlite,mysql, ...
- 四 Django框架,models.py模块,数据库操作——创建表、数据类型、索引、admin后台,补充Django目录说明以及全局配置文件配置
Django框架,models.py模块,数据库操作——创建表.数据类型.索引.admin后台,补充Django目录说明以及全局配置文件配置 数据库配置 django默认支持sqlite,mysql, ...
- PowerDesigner创建表 拷贝创建表语句 SQLSERVER创建数据库 使用查询 创建表 并且添加数据
PowerDesigner创建表 : 1.双击打开PowerDesigner 2.双击打开Create model 3左键点击Model types,再点击Physical Data m ...
- sybase从表A创建表B
sybase从表A创建表B 例如:需要创建一张表B,表的内容及结构跟表A完全一样,类似于SQL SERVER中的CREATE TABLE A AS SELECT * FROM B; 在sybase中只 ...
- Django基础(3)----模型层-单表操作,多表创建
昨日内容回顾: 1. {% include '' %} 2. extend base.html: <html> ..... ..... ..... {% block content%} { ...
- Oracle常用操作——创建表空间、临时表空间、创建表分区、创建索引、锁表处理
摘要:Oracle数据库的库表常用操作:创建与添加表空间.临时表空间.创建表分区.创建索引.锁表处理 1.表空间 ■ 详细查看表空间使用状况,包括总大小,使用空间,使用率,剩余空间 --详细查看表空 ...
- [No000005]C#注册表操作,创建,删除,修改,判断节点是否存在
//用.NET下托管语言C#操作注册表,主要内容包括:注册表项的创建,打开与删除.键值的创建(设置值.修改),读取和删除.判断注册表项是否存在.判断键值是否存在. //准备工作: //1:要操作注册表 ...
- PostgreSQL连接python,postgresql在python 连接,创建表,创建表内容,插入操作,选择操作,更新操作,删除操作。
安装 PostgreSQL可以用Python psycopg2模块集成. sycopg2是Python编程语言的PostgreSQL数据库的适配器. 其程序代码少,速度快,稳定.不需要单独安装这个模块 ...
- delphi 注册表操作(读取、添加、删除、修改)完全手册
DELPHI VS PASCAL(87) 32位Delphi程序中可利用TRegistry对象来存取注册表文件中的信息. 一.创建和释放TRegistry对象 1.创建TRegistry对象.为了操 ...
- c# 注册表操作,创建,删除,修改,判断节点是否存在
用.NET下托管语言C#操作注册表,主要内容包括:注册表项的创建,打开与删除.键值的创建(设置值.修改),读取和 删除.判断注册表项是否存在.判断键值是否存在. 准备工作: 1:要操作注册表,我们必须 ...
随机推荐
- linux centos5.8装yum安装mysql
默认的yum安装mysql都是5.1版本的 想要安装5.7的可以进行配置rpm包进行, mysql5.7安装路径 下面是默认的5.1安装路径 首先我们在使用yum安装的的时候会默认使用最新安装的,最 ...
- 如何制作 Objective-C 的UML图 [2]
如何制作 Objective-C 的UML图 [2] 说明 本教程旨在教你如何制作 Objective-C 的UML图,此为第二部分. 步骤 类继承关系 一个类符合某个协议 一个类认识另外一个对象(仅 ...
- Linux ss命令详解
ss是Socket Statistics的缩写.顾名思义,ss命令可以用来获取socket统计信息,它可以显示和netstat类似的内容.ss的优势在于它能够显示更多更详细的有关TCP和连接状态的信息 ...
- CSS学习摘要-布局
注:全文摘自MDN-介绍CSS布局 CSS页面布局技术允许我们拾取网页中的元素,并且控制它们相对正常布局流.周边元素.父容器或者主视口/窗口的位置.在这个模块中将涉及更多关于页面布局技术的细节: 浮动 ...
- jumpserver 问题,给自己看的哦,你们不准看哟
给自己看的,排版忽略! http://docs.jumpserver.org/zh/docs/setup_by_centos7.html 看完全部文档后解决不了再看下边的!!! docker 服务启动 ...
- thinkphp导出csv文件,用表格输出excel
1.thinkphp导出csv文件 导出csv文件可能就那几行代码,今天有个问题困扰我好久,就是导出之后出现一些html代码,这个不应该,view里面是空的,controller中最后也没有$this ...
- IDL创建泰森多边形
结果图: 附加源码: PRO testVoronoi idx = 0 ; 创建离散点 CASE idx OF ; 随机离散点 0: BEGIN N = 36 X = RANDOMN(seed, N) ...
- Shell定时删除日志
vim del_log.sh #!/bin/bash location="/home/dl/code/logs" find $location -mtime +4 -type f ...
- 【FLEX教程】#008 开发中的问题笔记(慢更…)
在这里记录一下个人在FLEX开发中遇到的一些问题.方便一些遇到同样问题的朋友们,能够快速的解决这些问题. 这篇笔记我会慢慢的更新,(PS:有遇到问题就往上面更….) 2015年1月4日 12:53:5 ...
- Day9 JSP
JSP概述 JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术.JSP实际上就是Servlet. jsp = html + ...