多表查询
外键
一对一
常用的放这张表
publish_detail | ||
---|---|---|
id | tel | |
1 | ||
多对一
被关联的表 的数据(先写,才可被关联)不可改,不可删
fk_publish 写关联的表 无所谓
publish | fk+unique(1对1) | |
---|---|---|
id | name | publish_detail_id |
1 | 20期 | 1、2不能重复 |
book | fk_publish | |
---|---|---|
id | title | publish_id |
1 | python | 1 |
多对多
互相建外键,不行,谁先建?
建第三张表
多对多 有外键,不可删23 也可以增加4 可以删除author里的1
book2authot | fk_book | fk_author |
---|---|---|
id | book_id | author_id |
1 | 1 | 2 |
2 | 1 | 3 |
3 |
author | ||
---|---|---|
id | name | 技术描述 |
1 | cls | 还行 |
很多公司不用foreign_key 了,牵一发而动全身,强制约束,导致操作变复杂
现在通过逻辑来+,建没有关系的表,inner join查。
写一段orm语句,写一段原生sql
select author.技术描述 from (select * from (从硬盘到内存) book inner join author on book.id == author.id) as t1 inner join book2author on t1.id == book2author.id;
book表,既有多对一,又有多对多,
我关联别人的,有范围
别人关联我,我随便增加
改和删不行。别人有关联的。
orm怎么操作多表的增删改查
多对多的三种创建
方式1 手动创建
class
联合唯一: 同时不重复
方式2 manytomany
方式3 manytomany 手动指定
through 指定这个表作为第三张表 指定字段
decimal为什么精度最高?存的是字符串,所以不会改变
再存浮点型的时候,小数点,存储机制,所以会变化。。。
show create table app01_author; 查询key
UNIQUE KEY ad_id_id
(ad_id_id
), 指定了后者,名字前者
alter table app01_author drop index ad_id_id; 删除uninkey
他连别人,所以可以随便删除,但是不可以随便添加
别人连他,所以可以随便添加,但是不可以随便删除
views
from django.shortcuts import render,HttpResponse
from app01 import models
# Create your views here.
def query(request):
# publish_obj = models.Publish.objects.filter(name='人民邮电')[0]
# publish_obj = models.Publish.objects.filter(id=2)[0]
# models.Book.objects.create(
# title='python3',
# price= 100,
# # publish= publish_obj, #方式1
# publish_id = 2,
# )
# models.Book.objects.filter(id=4).delete() # 删除和更新记录和单表是一样的
# models.Book.objects.filter(id=2).update(price = 200)
# 一对一
# models.Author.objects.create(
# name = 'yang',
# age = 18,
# # ad_id= models.AuthorDetail.objects.get(id = 1), #.id 在类里添
# ad_id_id= 2 , # 在数据库里添
# )
# 更新和删除
models.Author.objects.filter(id=2).update(name= 'wang')
# models.Author.objects.filter(id=2).delete()
# 多对多的增删改
#增加: 添加一本书,关联两个作者
# 1.先把作者录入了 , 然后选择
# 2. 或者输入作者,去查询
book_obj = models.Book.objects.create(
title='python3',
price= 100,
publish_id = 2,
)
# author1 = models.Author.objects.get(id=1)
# author3 = models.Author.objects.get(id=2)
book_obj = models.Book.objects.get(id=2)
# book_obj.authors.add(1,2)
# book_obj.authors.add(author1,author3) #book_obj.authors 找到了第三张表,添加
#除了放对象还可以放id
book_obj.authors.add(*[1,2]) #用的比较多
#删除
# book_obj.authors.remove(1) # authors 连接第三方,里面的是author对象或者id
# book_obj 已经是bookid为2 了 class Book表指向了author表(to 'author')
# book_obj.authors.remove(1,3) # authors 连接第三方,里面的是author对象或者id
# book_obj.authors.remove(*[1,3]) # authors 连接第三方,里面的是author对象或者id
book_obj.authors.clear() #清空为3 的所有关系 全部清除
book_obj.authors.set(['1',]) #清空所有的book_id 为3的第三张表里的所有记录
# authors连接第三张表,再重新写上book_id为3的对应的author_id 为1的 不是前几个作者写的,直接删前的,加后面的
book_obj.authors.set(['1','3']) #清空所有的book_id 为3的第三张表里的所有记录
return HttpResponse('ok')
models
from django.db import models
# Create your models here.
class AuthorDetail(models.Model):#不常用的放到这个表里面
'''
作者详细信息表
''' #不大常使用的字段,另建一个表,否则数据量大
# nid = models.AutoField(primary_key=True)
birthday=models.DateField()
telephone=models.BigIntegerField()
addr=models.CharField( max_length=64)
class Author(models.Model): #比较常用的信息放到这个表里面
'''
作者表
'''
name=models.CharField( max_length=32)
age=models.IntegerField()
# 与AuthorDetail建立一对一的关系,一对一的这个关系字段写在两个表的任意一个表里面都可以
# authorDetail=models.OneToOneField(to="AuthorDetail",to_field="nid",on_delete=models.CASCADE) #就是foreignkey+unique,只不过不需要我们自己来写参数了,并且orm会自动帮你给这个字段名字拼上一个_id,数据库中字段名称为authorDetail_id
# ad_id = models.OneToOneField(to='AuthorDetail',to_field='nid') #1对1
ad_id = models.OneToOneField(to='AuthorDetail' ) #1对1 不写默认关联主键 id 不用写级联删除,默认级联
# ad_id = models.OneToOneField(to='AuthorDetail',on_delete=models.SET_NULL,null=True ) #1对1 不写默认关联主键 id 不用写级联删除,默认级联
# 允许为null 如果删了关联的对应值 不级联 (我改我的) 级联,我改了,你也变
# book = models.ManyToManyField(to='Book',) # 生成一个表名 多对多的 在写,生成两个表
class Publish(models.Model):
name=models.CharField( max_length=32)
city=models.CharField( max_length=32)
#多对多的表关系,我们学mysql的时候是怎么建立的,是不是手动创建一个第三张表,然后写上两个字段,每个字段外键关联到另外两张多对多关系的表,orm的manytomany自动帮我们创建第三张表,两种方式建立关系都可以,以后的学习我们暂时用orm自动创建的第三张表,因为手动创建的第三张表我们进行orm操作的时候,很多关于多对多关系的表之间的orm语句方法无法使用
#如果你想删除某张表,你只需要将这个表注销掉,然后执行那两个数据库同步指令就可以了,自动就删除了。
class Book(models.Model):
title = models.CharField( max_length=32)
price=models.DecimalField(max_digits=5,decimal_places=2)
# 与Publish建立一对多的关系,外键字段建立在多的一方,字段publish如果是外键字段,那么它自动是int类型
publish=models.ForeignKey(to="Publish") # 多对一 foreignkey里面可以加很多的参数,都是需要咱们学习的,慢慢来,to指向表,to_field指向你关联的字段,不写这个,默认会自动关联主键字段,on_delete级联删除
# 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表,并且注意一点,你查看book表的时候,你看不到这个字段,因为这个字段就是创建第三张表的意思,不是创建字段的意思,所以只能说这个book类里面有authors这个字段属性
authors=models.ManyToManyField(to='Author',) #多对多 注意不管是一对多还是多对多,写to这个参数的时候,最后后面的值是个字符串,不然你就需要将你要关联的那个表放到这个表的上面