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 多表操作,创建表,添加记录的更多相关文章

  1. 第三百零六节,Django框架,models.py模块,数据库操作——创建表、数据类型、索引、admin后台,补充Django目录说明以及全局配置文件配置

    Django框架,models.py模块,数据库操作——创建表.数据类型.索引.admin后台,补充Django目录说明以及全局配置文件配置 数据库配置 django默认支持sqlite,mysql, ...

  2. 四 Django框架,models.py模块,数据库操作——创建表、数据类型、索引、admin后台,补充Django目录说明以及全局配置文件配置

    Django框架,models.py模块,数据库操作——创建表.数据类型.索引.admin后台,补充Django目录说明以及全局配置文件配置 数据库配置 django默认支持sqlite,mysql, ...

  3. PowerDesigner创建表 拷贝创建表语句 SQLSERVER创建数据库 使用查询 创建表 并且添加数据

    PowerDesigner创建表 : 1.双击打开PowerDesigner   2.双击打开Create model 3左键点击Model  types,再点击Physical    Data  m ...

  4. sybase从表A创建表B

    sybase从表A创建表B 例如:需要创建一张表B,表的内容及结构跟表A完全一样,类似于SQL SERVER中的CREATE TABLE A AS SELECT * FROM B; 在sybase中只 ...

  5. Django基础(3)----模型层-单表操作,多表创建

    昨日内容回顾: 1. {% include '' %} 2. extend base.html: <html> ..... ..... ..... {% block content%} { ...

  6. Oracle常用操作——创建表空间、临时表空间、创建表分区、创建索引、锁表处理

    摘要:Oracle数据库的库表常用操作:创建与添加表空间.临时表空间.创建表分区.创建索引.锁表处理 1.表空间 ■  详细查看表空间使用状况,包括总大小,使用空间,使用率,剩余空间 --详细查看表空 ...

  7. [No000005]C#注册表操作,创建,删除,修改,判断节点是否存在

    //用.NET下托管语言C#操作注册表,主要内容包括:注册表项的创建,打开与删除.键值的创建(设置值.修改),读取和删除.判断注册表项是否存在.判断键值是否存在. //准备工作: //1:要操作注册表 ...

  8. PostgreSQL连接python,postgresql在python 连接,创建表,创建表内容,插入操作,选择操作,更新操作,删除操作。

    安装 PostgreSQL可以用Python psycopg2模块集成. sycopg2是Python编程语言的PostgreSQL数据库的适配器. 其程序代码少,速度快,稳定.不需要单独安装这个模块 ...

  9. delphi 注册表操作(读取、添加、删除、修改)完全手册

    DELPHI VS PASCAL(87)  32位Delphi程序中可利用TRegistry对象来存取注册表文件中的信息. 一.创建和释放TRegistry对象 1.创建TRegistry对象.为了操 ...

  10. c# 注册表操作,创建,删除,修改,判断节点是否存在

    用.NET下托管语言C#操作注册表,主要内容包括:注册表项的创建,打开与删除.键值的创建(设置值.修改),读取和 删除.判断注册表项是否存在.判断键值是否存在. 准备工作: 1:要操作注册表,我们必须 ...

随机推荐

  1. Breathing During Sleep

    TPO24-2 Breathing During Sleep Of all the physiological differences in human sleep compared with wak ...

  2. Mysql使用binlog恢复数据解决误操作问题的两种方法

    为保证没有其他参数配置影响,重新安装配置了一台最小化安装的CentOS7虚拟机 1. 基础知识
 安装mysql5.6数据库Mysql binlog初步理解 2. 配置mysql 开启binlog.修 ...

  3. 解决Failed to load the JNI shared library xxx/xxx/jvm.dll 错误

    原因:jdk发生变化(新装了32位jdk),eclipse在启动时使用了 系统环境变量中的jdk路径(32位). 解决:只要把旧的64位的jre路径指定给eclipse启动文件即可. 在eclipse ...

  4. [EffectiveC++]item32:确定你的public继承模塑出is-a关系

  5. 面向对象程序设计__Task3_Calculator

    The initial part of the Calculator program 题目链接:Click Here github链接:Click Here 看到这个题目的话,想到就是有3个任务要去做 ...

  6. PHP设计模式系列 - 单例

    单例模式 通过提供自身共享实例的访问,单例设计模式用于限制特定对象只能被创建一次. 使用场景 例如数据库实例,一般都会走单例模式. 单例模式可以减少类的实例化 代码:来源InitPHP框架,先检测类有 ...

  7. Java Classloader机制解析

    做Java开发,对于ClassLoader的机制是必须要熟悉的基础知识,本文针对Java ClassLoader的机制做一个简要的总结.因为不同的JVM的实现不同,本文所描述的内容均只限于Hotspo ...

  8. 前端面试总结——http、html和浏览器篇

    1.http和https https的SSL加密是在传输层实现的. (1)http和https的基本概念 http: 超文本传输协议,是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和 ...

  9. CentOS 7下启动、关闭、重启、查看MySQL服务

    1.启动命令 [root@xufeng Desktop]# service mysqld startRedirecting to /bin/systemctl start mysqld.service ...

  10. P3558 [POI2013]BAJ-Bytecomputer

    题目描述 A sequence of integers is given. The bytecomputer is a device that allows the following operati ...