day60

多表查询

外键

一对一

常用的放这张表

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这个参数的时候,最后后面的值是个字符串,不然你就需要将你要关联的那个表放到这个表的上面

猜你喜欢

转载自www.cnblogs.com/Doner/p/10930000.html