模型的关系

模型与模型之间的关系.或者理解为 表与表之间的关系

例如:班级与学员 文章与类型 新闻与新闻分类

  • 如何实现模型的关系:

    在一张表添加一个外键(外键就是当前表中的一个字段的值是另外一张表中的主键)。

    外键有 物理外键和逻辑外键(推荐)。

    物理外键会产生表与表直接的强耦合,可能会在并发时造成死锁,会造成程序的阻塞。

  • 有哪些关系?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    # 创建学员模型
    class Stu(models.Model):
    sname = models.CharField(max_length=6)
    age = models.IntegerField()
    # 一对多,一对一不用这条
    cid = models.ForeignKey(to="ClassInfo", to_field="id",on_delete=models.CASCADE)

    def __str__(self):
    return '<Stu: '+self.sname+' object>'

    # 创建学员详情模型
    class StuInfo(models.Model):
    jiguan = models.CharField(max_length=10)
    xueli = models.CharField(max_length=10)
    # 第一个参数:是被关联的模型名称
    # 第二个参数:当关联表中的一条数据被删除的时候,与之对应的详情表数据也会被删除
    uid = models.OneToOneField(Stu, on_delete=models.CASCADE)

    # 定义 班级 模型
    class ClassInfo(models.Model):
    cname = models.CharField(max_length=10)
    code = models.IntegerField()

    # 书籍
    class Books(models.Model):
    title = models.CharField(max_length=50)
    author = models.CharField(max_length=50)

    # 标签
    class Tags(models.Model):
    name = models.CharField(max_length=10)
    # 多对多关系定义
    bid = models.ManyToManyField(to="Books")

    def __str__(self):
    return '<Tags: '+self.name+' object>'

    一对一(逻辑外键,只需两表之间有相同的列)

    就是一个表中数据与另外一个表中的数据是相关联的,并且只与一条数据关联

    例如:一个学员信息只对应一个学员详情信息,一个学员详情信息也只对应一个学员信息,即学员信息或学员详情信息有对方相同的一个列.

    学员信息
    
     姓名,性别,年龄,手机号,学历,...
    
    学员详情信息
    
     籍贯,住址,家属联系方式,....
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    # 创建视图函数 演示 一对一模型关系的操作
    def onetoone(request):
    # 添加
    # # 创建学员信息
    ob = models.Stu(sname='李四',age=24)
    ob.save()

    # # 添加学员详情信息
    obi = models.StuInfo()
    obi.jiguan = '山西'
    obi.xueli = '大专'
    # 注意,在给外键添加数据时,只能选择对象,不能设为对象的id
    obi.uid = ob
    # obi.save()

    # 查询
    # 通过学员 获取学员详情
    ob = models.Stu.objects.first()
    print(ob.sname)
    print(ob.stuinfo) # 通过学员对象获取与之关联的 学员详情 对象
    print(ob.stuinfo.xueli)

    # 通过学员详情,获取学员信息
    ob = models.StuInfo.objects.last()
    print(ob.jiguan)
    print(ob.uid) # 通过学员详情对象 获取与之关联的 学员 对象
    print(ob.uid.sname)

    # 删除
    ob = models.Stu.objects.first()
    ob.delete()

    return HttpResponse('演示 一对一模型关系的操作')

    #去home应用的url.py添加路径
    re_path(r'onetoone/$',views.onetoone,name="onetoone"),

    一对多(物理外键,一个表中的某一列是另一个表的主键)

    一个班级 有多个学员,多个学员都在一个班级(外键要放在多的表中)

    一个表中的数据对应另外一个表中的多条数据,一张表中多个数据对应另外一个表中的一条数据,即一个表中的某一列是另一个表的主键.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    # 一对多的操作
    def onetomore(request):
    # 添加
    # # 创建班级
    ob = models.ClassInfo(cname="python17",code=707)
    ob.save()

    # # 创建学员
    sob = models.Stu(sname='王五',age=23,cid=ob)
    sob.save()

    # 查询
    # 通过班级,获取当前班级的所有学员
    ob = models.ClassInfo.objects.first()
    print(ob.cname)
    # 注意 与之关联的模型类名 小写_set.查询方法
    print(ob.stu_set.all())

    # 通过学员,获取当前学员所在班级
    ob = models.Stu.objects.last()
    print(ob.sname)
    print(ob.cid.cname)

    # 删除
    # ob = models.ClassInfo.objects.first()
    # ob.delete()

    return HttpResponse('一对多的操作')

    #去home应用的url.py添加路径
    re_path(r'onetomore/$',views.onetomore,name="onetomore"),

    多对多

    班级和老师,一个班级有多个老师,一个老师去多个班级授课

    书籍和标签,一本书有多个标签,一个标签下有多本书

    书籍:
    
    
    1
    2
    3
    4
    id      bname
    1 <<Python3.7从零开始学>>
    2 <<细说PHP>>
    3 <<细说Python数据分析>>
    标签:
    1
    2
    3
    4
    5
    id  tname
    1 Python
    2 PHP
    3 编程语言
    4 数据分析
    书籍和标签关系:
    1
    2
    3
    4
    5
    6
    7
    8
    bookid   tagid
    1 1
    1 3
    2 2
    2 3
    3 1
    3 3
    3 4
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    # 多对多的操作
    def manymomany(request):

    # 添加
    # 创建书籍
    b1 = models.Books(title='<<Python3.7从零开始学>>',author='刘宇宙')
    b2 = models.Books(title='<<跟兄弟连学PHP>>',author='高洛峰')
    b1.save()
    b2.save()

    # 创建标签
    t1 = models.Tags(name='Python')
    t2 = models.Tags(name='计算机编程')
    t3 = models.Tags(name='PHP')
    t1.save()
    t2.save()
    t3.save()

    # # 给书籍添加标签
    t1.bid.add(b1)
    t2.bid.add(b1)
    t2.bid.add(b2)
    t3.bid.add(b2)

    # 查询
    # 通过书 获取当前书下的所有标签
    b = models.Books.objects.first()
    print(b.title)
    print(b.author)
    print(b.tags_set.all())

    # 通过标签.获取当前标签下的所有书
    t = models.Tags.objects.get(id=2)
    print(t.name)
    # 注意,在使用有外键的模型进行相关查询时,使用外键属性即可
    print(t.bid.all())

    # 如果删除关系中的任何一个数据,对另外一个表数据不产生影响,但是会删除对应的关系数据
    # b = models.Books.objects.first()
    # b.delete()

    return HttpResponse('多对多的操作')

    #去home应用的url.py添加路径
    re_path(r'manymomany/$',views.manymomany,name="manymomany"),