美文网首页
十 Django模型关联关系

十 Django模型关联关系

作者: 唯老 | 来源:发表于2019-02-20 22:22 被阅读7次

一、前期概要

1.1 名词解释

  1. 关系:事物之间相互作用、相互联系的状态。
  2. 关联:名词:表示对象(数据库表)之间的关系;动词:将对象(数据库表)之间通过某种方式联系起来。
  3. 映射:将一种形式转化为另一种形式,包括关系。
  4. 级联:有关系的双方中操作一方,另一方也将采取一些动作
  5. 值类型:对象不具备数据库同一性,属于一个实体实例其持久化状态被嵌入到所拥有的实体的表行中,没有标识符。
  6. 实体类型:具有数据库标识符。

二、数据库关系

  1. 一对一(one-to-one)
  2. 多对一(many-to-one)
  3. 多对多(many-to-many)

三、模型

  1. 完整代码

    from django.db import models
    # Create your models here.
    class ClassRoom(models.Model):
        cls_id = models.AutoField(primary_key=True)
        cname = models.CharField(max_length=32)
        cdata = models.DateField(auto_now_add=True)
        class Meta:
            db_table = 'class_room'
    
        def __str__(self):
            return "%s" % [self.__class__, self.cname]
    class Student(models.Model):
        stu_id = models.AutoField(primary_key=True)
        stu_name = models.CharField(max_length=32)
        # 一对多
        cls_id = models.ForeignKey(to="ClassRoom", on_delete=models.SET_NULL, null=True, to_field='cls_id',db_column='cls_id')
                                   
        class Meta:
            db_table = 'student'
    
        def __str__(self):
            return "%s" % self.stu_name
    class StudentDetail(models.Model):
        stu_detail_id = models.AutoField(primary_key=True)
        height = models.PositiveIntegerField(null=True)
        email = models.EmailField(null=True)
        no = models.CharField(max_length=64)
        stu = models.OneToOneField('Student', on_delete=models.CASCADE, to_field='stu_id', null=True)
    
        class Meta:
            db_table = 'student_detail'
    
    class Teacher(models.Model):
        id = models.AutoField(primary_key=True)
        tea_name = models.CharField(max_length=32)
        cid = models.ManyToManyField(to="Student", name="teacher", db_table='teacher_student')
        class Meta:
            db_table = 'teacher'
    
    

四、一对一映射关系

1.1、概念

所谓的一对一查询,就是说我们在查询一个表的数据的时候,需要关联查询其他表的数据,例如:husband(丈夫)-wife(妻子) User和Account,一个用户对应一个账户,一个订单对应一个用户,一个学生信息对一个学生详情表

1.2、配置方式

  1. 语法

    OneToOneField(to, on_delete=None, to_field=None,db_column=None)
    
  2. 参数说明

    • to

      主表 对应类的名称

    • on_delete

      当一个被外键关联的对象被删除时,Django将模仿on_delete参数定义的SQL约束执行相应操作。比如,你有一个可为空的外键,并且你想让它在关联的对象被删除时,自动设为null

      常用可选值

      1、models.CASCADE 子表相关的数据删除
      2、models.SET_NULL 子表的数据不删除 外键字段设置null=True
      3、odels.SET_DEFAULT 子表关联数据不删除,在外键字段设置自定义的值

      4、DO_NOTHING:什么也不做。

      5、SET():设置为一个传递给SET()的值或者一个回调函数的返回值。注意大小写

    • related_name

      用于关联对象反向引用模型的名称。通常情况下,这个参数我们可以不设置,Django会默认以模型的小写作为反向关联名

    • to_field

      参照主表的字段 默认主键

  3. 关系模型

    image
  4. 对象模型

    class Student(models.Model):
        stu_id = models.AutoField(primary_key=True)
        stu_name = models.CharField(max_length=32)
    
        # 一对多
        cls_id = models.ForeignKey(to="ClassRoom", on_delete=models.SET_NULL, null=True, to_field='cls_id',db_column='cls_id')
                  
        class Meta:
            db_table = 'student'
    
        def __str__(self):
            return "%s" % self.stu_name
    
    class StudentDetail(models.Model):
        stu_detail_id = models.AutoField(primary_key=True)
        height = models.PositiveIntegerField(null=True)
        email = models.EmailField(null=True)
        no = models.CharField(max_length=64)
        stu = models.OneToOneField('Student', on_delete=models.CASCADE, to_field='stu_id', null=True)
        class Meta:
            db_table = 'student_detail'
    

1.3、添加

  1. 方式一

    # 先保存主表数据,然后将主表的id给子表的外键字段
    stu = Student.objects.create(stu_name='小明')
    StudentDetail.objects.create(stu=stu, email='123@163.com', no=175)
    
  2. 方式二

    stu = Student.objects.create(stu_name='小红')
    StudentDetail.objects.create(stu_id=stu.pk, email='345@163.com', no=170)
    
  3. 总结

    跟单表操作表,唯一需要注意的是往子表添加数据,主表的数据一定要先存在

1.4、修改

  1. 通过主表更新子表

    xm = Student.objects.get(pk=1)
    StudentDetail.objects.filter(stu=xm).update(no='123')
    
  2. 通过主表更新子表

    stu = StudentDetail.objects.get(stu_detail_id=2).stu
    stu.stu_name = '小花'
    stu.save()
    
  3. 总结

    跟单表操作比,如果提供的条件是有关系的表,通过关联关系找到相关的表的记录然后去更新,

1.5、查询

  1. 通过子表查询主表相关的信息(正向查询)

    stu = StudentDetail.objects.get(pk=1)
    print(stu.stu_name)
    
  2. 通过主表查询子表相关的信息(反向查询)

    # 系统会自动创建一个 类名小写的字段对象
    stu = Student.objects.get(pk=1)
    # 类名字的小写
    print(stu.stu_name, stu.studentdetail.email, str(stu.studentdetail.stu_detail_id))
    
  3. 通过主表的条件查询子表数据(可以使用双下划线)

    # 一对一的子表字段__母表字段="xxx"
    # 相当于sql里的等值连接
    sd = StudentDetail.objects.filter(stu__stu_name='小明')
    # 等同于
    # stu_id = Student.objects.get(stu_name='小明').stu_id
    # sd = StudentDetail.objects.filter(stu_id=stu_id)
    # 也可以 
    stu = Student.objects.get(stu_name='小明')
    print(stu.studentdetail)
    
  4. 总结

    • 通过查询主表,会自动帮我们关联查询子表的数据, 使用主表对象.类名小写的方式
    • 通过主表查询子表,如果查询的条件是主表可以直接使用子表字段__母表字段

1.6、删除

  1. 通过主表删除子表数据 跟on_delete删除设置有关
stu = Student.objects.get(pk=1)
stu.delete()
# 子表数据删除不影响主表数据跟普通单表的删除一样
  1. 删除子表数据的时候建议使用 假删除

    在主表添加额外的字段

    1 表示正常 0表示删除
    is_delete = models.BooleanField(default=1)

    stu = Student.objects.get(pk=1)
    stu.is_delete = 0
    stu.save()
    # 查询的时候把删除的字段加上
    # Student.objects.filter(stu_name='隔壁小张', is_delete=1)
    
  2. 总结

    删除主表数据对子表数据有影响,主要跟on_delete设置的值有关系,删除子表数据一般情况下跟主表没有太多的关系

五、一对多映射关系

2.1、概念

一对多关联是一方持有多方引用。例如:去京东购物,那么一个京东用户可以对应多个购物订单

2.2、配置方式

  1. 语法格式

    ForeignKey(to, on_delete, **options)
    
  2. 参数说明

    • to

      主表 对应类的名称

    • on_delete

      当一个被外键关联的对象被删除时,Django将模仿on_delete参数定义的SQL约束执行相应操作。比如,你有一个可为空的外键,并且你想让它在关联的对象被删除时,自动设为null

      常用可选值

      1、models.CASCADE 子表相关的数据删除
      2、models.SET_NULL 子表的数据不删除 外键字段设置null=True
      3、odels.SET_DEFAULT 子表关联数据不删除,在外键字段设置自定义的值

      4、DO_NOTHING:什么也不做。

      5、SET():设置为一个传递给SET()的值或者一个回调函数的返回值。注意大小写

    • related_name

      用于关联对象反向引用模型的名称。通常情况下,这个参数我们可以不设置,Django会默认以模型的小写作为反向关联名

    • to_field

      参照主表的字段 默认主键

  3. 关系模型

    image
  4. 对象模型

    class ClassRoom(models.Model):
        cls_id = models.AutoField(primary_key=True)
        cname = models.CharField(max_length=32)
        cdata = models.DateField(auto_now_add=True)
    
        class Meta:
            db_table = 'class_room'
    
        def __str__(self):
            return "%s" % [self.__class__, self.cname]
    
    class Student(models.Model):
        stu_id = models.AutoField(primary_key=True)
        stu_name = models.CharField(max_length=32)
    
        # 一对多
        cid = models.ForeignKey(to="ClassRoom", db_column='cls_id')
     
        class Meta:
            db_table = 'student'
    
        def __str__(self):
            return "%s" % [self.stu_name]
    

2.3、查询操作

  1. 通过主表查询子表

    tea = Teacher.objects.filter(pk=1).first()
    stu_list = tea.student_set.all()
    for stu in stu_list:
        print(stu.stu_name)
    
  2. 也可以使用__双下划线方式(推荐)

    sd = StudentDetail.objects.filter(stu__stu_name='小明')
    print(sd)
    

2.4、添加(跟一对一相同)

  1. 添加子表数据,往子表添加数据,主表的数据必须先存在

    teacher = Teacher.objects.create(tea_name='隔壁小张')
    print(teacher.id)
    for index in range(10):
     Student(stu_name='test' + str(index), teacher_id=teacher.pk).save()
    
  2. 总结

    • 添加主表数据对子表没有影响
    • 往子表添加数据,主表的数据必须先存在

2.4、更新(跟一对一相同)

  1. 更新数据跟普通的操作没有太多的影响

    room = ClassRoom.objects.filter(cname='实训1').first()
    num = room.student_set.filter(stu_id__gt=1).update(stu_name='111')
    print(num)
    
  2. 总结

    通过主表查询子表的时候注意隐藏django会自动给我们创建一个类名_set的一个引用属性

相关文章

  • 十 Django模型关联关系

    一、前期概要 1.1 名词解释 关系:事物之间相互作用、相互联系的状态。 关联:名词:表示对象(数据库表)之间的关...

  • Django 2.1.7 模型管理器 models.Manage

    上一篇Django 2.1.7 模型的关联讲述了关于Django模型一对多、多对多、自关联等模型关系。 在查询数据...

  • Django模型关联操作

    Django中的模型与模型之间一般会存在关联关系,如以下两个表: 英雄模型通过 book = models.For...

  • django模型中关联关系查询

    写的很乱,写的时候思路不够清晰 django中模型多对多关系 ForeignKey外键约束,在django中是表示...

  • Django模型(四)

    Django模型 知识点: 表关联对象 多表查询 表关联对象 前向查询 如果一个模型具有ForeignKey,那么...

  • Django 多表关联

    1. 一对一关联关系 使用方法数据库体现Django程序模型通过外键关联,外键要设在多的一方OneToOneFie...

  • Django模型-自关联

    新建模型AreaInfo,生成迁移 class AreaInfo(models.Model): atitle = ...

  • django admin 关联模型

  • Django模型

    Django是怎么链接数据库的呢。 django模型映射关系:模型类 >>>>>>>>>>>>>>>数据库类属性>...

  • 模型关联关系

    模型的对应关系主要分为:一对一,一对多,以及多对多。 模型对应关系描述如下:1:1 一对一 OneToOneFie...

网友评论

      本文标题:十 Django模型关联关系

      本文链接:https://www.haomeiwen.com/subject/oxnkyqtx.html