7、Django的orm之多表操做(一)

多表操做python

三种关系:一对一,一对多,多对多mysql

1、数据准备,建立表模型git

  1. 配置settings,链接到数据库
    # settings更改配置
    DATABASES = {
    'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': 'orm03',
    'HOST':'127.0.0.1',
    'PORT':3306,
    'USER':'root',
    'PASSWORD':'123'
    }
    }sql

    # 项目中的init写入:
    import pymysql
    pymysql.install_as_MySQLdb()
  2. 在应用中的models.py建立模型
    from django.db import models数据库

    # 比较经常使用的信息放到这个表里面
    class Author(models.Model): 
        nid = models.AutoField(primary_key=True)
        name=models.CharField( max_length=32)
        age=models.IntegerField()
        authorDetail=models.OneToOneField(
            to="AuthorDetail",
            to_field="nid",
            on_delete=models.CASCADE      # on_delete=models.SET_NULL()设置不级连删除,对方删除后,本身设置为空
        )
        # 与AuthorDetail创建一对一的关系(OneToOneField),一对一的这个关系字段写在两个表的任意一个表里面均可以
        # 就是foreignkey+unique,只不过不须要咱们本身来写参数了,而且orm会自动帮你给这个字段名字拼上一个_id,数据库中字段名称为authorDetail_id
    
    
    # 不经常使用的放到这个表里面
    class AuthorDetail(models.Model):
    
        nid = models.AutoField(primary_key=True)
        birthday=models.DateField()
        # telephone=models.BigIntegerField() 不方便之后查询,须要再转str查,不如直接用str类型
        telephone=models.CharField(max_length=30)
        addr=models.CharField(max_length=64)
     # 与Author创建一对一的关系(OneToOneField这个关系字段写在两个表的任意一个表里面均可以)
    
    
    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()  # 至关于CharField,后期可多一层校验规则,判断是不是xx.@...这样的邮箱地址
    
     # 多对多的表关系,在mysql的时候创建这种关系,须要手动建立一个第三张表,而后写上两个字段,每一个字段外键关联到另外两张多对多关系的表;orm的manytomany自动帮咱们建立第三张表,两种方式创建关系均可以,之后的学习咱们暂时用orm自动建立的第三张表,由于手动建立的第三张表咱们进行orm操做的时候,不少关于多对多关系的表之间的orm语句方法没法使用
    #若是你想删除某张表,你只须要将这个表注销掉,而后执行那两个数据库同步指令就能够了,自动就删除了。
    
    
    # 与Publish创建一对多的关系
    # 与Author创建多对多的关系
    class Book(models.Model):
    
        nid = models.AutoField(primary_key=True)
        title = models.CharField( max_length=32)
        publishDate=models.DateField()
        price=models.DecimalField(max_digits=5,decimal_places=2)    
        publish=models.ForeignKey(
            to="Publish",
            to_field="nid",
            on_delete=models.CASCADE
        )
        # 与Publish创建一对多的关系,外键字段创建在多的一方,字段publish若是是外键字段,那么它自动是int类型
    
        #foreignkey里面能够加不少的参数,to指向表,to_field指向你关联的字段,不写这个,默认会自动关联主键字段,on_delete级联删除
        #字段名称不须要写成publish_id,orm在翻译foreignkey的时候会自动给你这个字段拼上一个_id,这个字段名称在数据库里面就自动变成了publish_id
        # 与Author表创建多对多的关系,ManyToManyField能够建在两个模型中的任意一个,自动建立第三张表,而且注意一点,你查看book表的时候,你看不到这个字段,由于这个字段就是建立第三张表的意思,不是建立字段的意思,因此只能说这个book类里面有authors这个字段属性
        authors=models.ManyToManyField(to='Author')
        # 注意不论是一对多仍是多对多,写to这个参数的时候,最后后面的值是个字符串,否则你就须要将你要关联的那个表放到这个表的上面

    总结:
    建立表:django

    一对一:# OneToOneField
     xx = models.OneToOneField(
            to='表名',
            to_field='字段名',
            on_delete=models.CASCADE
        )
        # to_field能够不写,默认是关联到另外一张表的主键
        # on_delete在1.x版本的django中不用写,默认是级联删除的,2.x版本的django要写
        # on_delete=models.SET_NULL()设置不级连删除,对方删除后,本身设置为空
    
    一对多:# ForeignKey
     xx = models.ForeignKey(
            to='表名',
            to_field='字段名',
            on_delete=models.CASCADE
        )
    
    多对多:# ManyToManyField
     xx = models.ManyToManyField(to='另一个表名') #这是自动建立第三表
     # 还能够手动建立第三张表,(用在还有其余一些本身的字段的时候,暂时忽略)
     # class BookToAuthor(models.Model):
     #     book_id = models.ForeignKey(to='Book')
     #     author_id = models.ForeignKey(to='Author')
     #     xx = models.CharField(max_length=12)
    
    注意:不论是一对多仍是多对多,写to这个参数的时候,最后后面的值是个字符串,否则你就须要将你要关联的那个表放到这个表的上面
  3. 执行数据库同步指令:
    python manage.py makemigrations
    python manage.py migrate
    结果以下:app

2、关系表添加记录
学习

拓展一种添加数据的方式,是django内部提供的一个后台管理系统翻译

  1. 建立一个超级用户:
    python manage.py createsuperuser3d

    Username (leave blank to use 'administrator'):  yangzm
    Email address:  
    Password:  94211314ming.
  2. 访问127.0.0.1:8000/admin/,使用刚注册好的用户名、密码,登陆后台管理系统

  3. 在应用app01下的admin.py注册咱们要用的表
    from django.contrib import admin
    from app01 import models # 导入models

    # Register your models here.
    
    admin.site.register(models.Author)   # admin.site.register方法注册
    admin.site.register(models.Publish)
    admin.site.register(models.Book)
    admin.site.register(models.AuthorDetail)
  4. 从新运行项目,就会发现表已经在后台的管理系统当中了

  5. 点击里面的添加按钮,根据要求,就能够添加数据了

  • 一对一表的增长
    一对一关联的表是:Author表的authorDetail字段关联的 AuthorDetail表的nid字段
    def query(request):

    new_author_detail = models.AuthorDetail.objects.create(
            birthday='1996-02-14',
            telephone='188753698755',
            addr='天界大陆'
        )
        # 方式1:
        models.Author.objects.create(
            name='liangdao',
            age='26',
            authorDetail=new_author_detail # 直接等于对象
        )
    
        new_author_obj = models.AuthorDetail.objects.create(
            birthday='1886-02-14',
            telephone='18615724935',
            addr='幽暗密林'
        )
        # 方式2:(经常使用)
        models.Author.objects.create(
            name='baobao',
            age='55',
            authorDetail_id=new_author_obj.nid  # 把对象的id属性关联起来
        )
  • 一对多的增长
    一对多关联的表是:Book表的publish字段关联的 Publish表的nid字段
    # 方式1:
    models.Book.objects.create(
    title='回村的诱惑',
    publishDate='2018-12-12',
    price=88.88,
    publish=models.Publish.objects.get(nid=1)
    )
    # 方式2:(经常使用)
    models.Book.objects.create(
    title='回村的诱惑2',
    publishDate='2000-11-11',
    price=45,
    publish_id=models.Publish.objects.get(nid=1).nid
    )

  • 多对多的增长
    多对多关联的表是:Book表的authors字段关联的 Author表的nid字段
    # 方式1:经常使用
    book_obj = models.Book.objects.get(nid=1)
    book_obj.authors.add([1,2])
    # 方式2:
    author1 = models.Author.objects.get(nid=1)
    author2 = models.Author.objects.get(nid=3)
    book_obj = models.Book.objects.get(nid=2)
    book_obj.authors.add(
    [author1, author2])

一对一和一对多的删除和单表删除是同样的

  • 一对一的删
    # Author表一对一关联AuthorDetail表
    models.AuthorDetail.objects.get(nid=2).delete()
    # 当AuthorDetail表删除数据时,会影响到Author表,由于级联删除
    models.Author.objects.get(nid=4).delete()
    # 当Author表删除数据时,不会影响到AuthorDetail表
    注意:
    • 表一关联表二,作了级联,表二删除,表一跟着删除
    • 表一关联表二,没作级联,表二删除,表一报错
    • 表一关联表二,不管作没作级联,表一删除数据,都不会影响到表二
  • 一对多的删
    # Book表一对多关联Publish表
    models.Publish.objects.get(nid=2).delete()
    # Publish表删除数据,影响到Book表
    models.Book.objects.get(nid=7).delete()
    # Book表删除数据,不会影响到Publish表

  • 多对多关系的删除
    实际上就是去删除多对多自动生成的表中的关系的记录
    # Book表多对多的关联Author表
    book_obj = models.Book.objects.get(nid=3)
    book_obj.authors.remove(3)
    # 先找到book里id是3的书,而后经过authors属性删除做者id是3的数据

    book_obj = models.Book.objects.get(nid=3)
        book_obj.authors.remove(*[2,3])
        # 先找到book里id是3的书,而后经过authors属性删除做者id是2和3的数据
    
        book_obj = models.Book.objects.get(nid=3)
        book_obj.authors.clear()
        # 先找到book里id是3的书,而后经过authors属性找到关系表,删除全部id是3的书数据
    
        book_obj = models.Book.objects.get(nid=3)
        book_obj.authors.clear()
        book_obj.authors.add(*[1,])
        # 先删除全部id是3的书数据,而后给id是3的书加入一个id是1的做者
    
        book_obj = models.Book.objects.get(nid=3)
        book_obj.authors.set('1')
        # 一样完成上述需求,先清空再添加(set必须给个参数,不然报错)
    
        book_obj = models.Book.objects.get(nid=3)
        book_obj.authors.set(['5','6']) 
        # 删除而后更新,添加多个
    注意:
    • Book表删除数据,会影响到关系表的数据
    • Author表删除数据,也一样会影响到关系表的数据
  1. 更新
  • 一对一
    models.Author.objects.filter(nid=6).update(
    name='baoge',
    age='16',
    authorDetail=models.AuthorDetail.objects.get(nid=5)
    # authorDetail_id = 4 两种方式
    )

  • 一对多
    models.Book.objects.filter(pk=6).update(
    title='回娘家的诱惑',
    price=188,
    publish=models.Publish.objects.get(pk=2)

    models.Publish.objects.filter(pk=2).update(
          id=4, # 没有级联更新,报错!!
        )
    
    # 注:默认级联删除,级联更新没有默认
  • 多对多
    # 就是set

    book_obj = models.Book.objects.get(nid=3)
        book_obj.authors.set('1')
        # 一样完成上述需求,先清空再添加(set必须给个参数,不然报错)
    
        book_obj = models.Book.objects.get(nid=3)
        book_obj.authors.set(['5','6']) 
        # 删除而后更新,添加多个
相关文章
相关标签/搜索