《Django Web应用开发实战》学习笔记 15- Django模型关系(1对1、1对多、多对多)

学习资料

《Django Web应用开发实战》

数据表关系

一个模型对应数据库的一张表,但是每张数据表之间是可以存在外键关联的,表与表之间有3种关联:一对一、一对多、多对多

1.1 一对一关系

一对一关系存在于两张表种,第一张表的某一行数据只与第二张表的某一行数据相关,这种表被称为一对一关系

一对一关系的第一张表A

ID 姓名 国籍 参加节目
1001 王大锤 中国 万万没想到
1002 全智贤 韩国 蓝色大海的传说
1003 刀锋女王 未知 计划生育

一对一关系的第二张表B

ID 始于 终于
1001 1988 NULL
1002 1981 NULL
1003 未知 3XXX

表A、B的字段ID分别是一一对应的,并且ID不会重复,使用这种外键关联通常是一张数据表设有太多字段,将常用的字段抽取出来并弄成一张新表,在模型中可以通过OneToOneField来构建数据表的一对一关系

from django.db import models


class Performer(models.Model):
    """相当于表A"""
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=10)
    nationality = models.CharField(max_length=30)
    masterpiece = models.CharField(max_length=50)
    
    
class PerformerInfo(models.Model):
    """相当于表B"""
    id = models.IntegerField(primary_key=True)
    performer = models.OneToOneField(Performer, on_delete=models.CASCADE)
    birth = models.CharField(max_length=20)
    elapse = models.CharField(max_length=20)

Snipaste_2020-11-26_20-44-37.png

1.2 一对多关系

一对多关系存在于两张或者两张以上的数据表中,第一张表的某一行以于第二张表的一到多行数据进行关联,但是第二张表的每一行数据只能于第一张表的某一行进行关联

一对多关系的第一张表AA

ID 姓名 国籍
1001 王大锤 中国
1002 全智贤 韩国
1003 刀锋女王 未知

一对多关系的第二张表BB

ID 节目
1001 万万没想到
1002 报告老板
1003 星际2
1003 英雄联盟

表AA字段ID的数据不可以重复,但表BB的ID可以重复,字段ID相同的数据对应表AA中的某一行数据,这种表关系在日常开发中更为常见,可以通过ForeignKey来构建一对多关系

# 一对多
from django.db import models
class Performer(models.Model):
    """相当于表AA"""
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=10)
    nationality = models.CharField(max_length=30)


class Program(models.Model):
    """相当于表BB"""
    id = models.IntegerField(primary_key=True)
    performer = models.ForeignKey(Performer, on_delete=models.CASCADE)
    name = models.CharField(max_length=50)

Snipaste_2020-11-26_20-57-53.png

1.3 多对多关系

多对多关系存在于两张或两张以上的数据表中,第一张表的某一行数据可以与第二张表的某一到多行数据进行关联,同时第二张表中的某一行数据也可以与第一张表的一到多行数据进行关联
多对多关系的第一张表AAA

ID 姓名 国籍
1001 王大锤 中国
1002 全智贤 韩国
1003 刀锋女王 未知

多对多关系的第二张表BBB

ID 节目
10001 万万没想到
10002 报告老板
10003 星际2
10004 英雄联盟

AAA与BBB两张表的数据关系

ID 节目ID 演员ID
1 10001 1001
2 10001 1002
3 10002 1001

上述表中可以发现,一个演员可以参加多个节目,而一个节目亦可以由多个演员来共同演出,每张表的字段ID都是唯一的,从AAA与BBB数据关系表可以发现,节目ID和演员ID出现了重复的数据分别对应AAA和BBB的字段ID,多对多关系需要使用新的数据表来管理两张表的数据关系,在模型中可以通过ManyToManyField来构建关系

# 多对多
from django.db import models
class Performer(models.Model):
    """相当于表AAA"""
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=10)
    nationality = models.CharField(max_length=30)


class Program(models.Model):
    """相当于表BBB"""
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=50)
    performer = models.ManyToManyField(Performer)

PS:第三张表在执行迁移和生成命令时自动生成在数据库中

Snipaste_2020-11-26_21-10-28.png

OneToOneField、ForeignKey、ManyToManyField的特殊参数

参数 描述
to 必选参数,关联的模型名称(类名)
on_delete 必选参数,设置数据的删除模式,包括CASCADE、PROTECT、SET_NULL、SET_DEFAULT、SET、DO_NOTHING
limit_choices_to 设置外键的下拉框选项,用于模型表单和Admin后台系统
related_name 用于模型之间的关联查询,如反向查询
related_query_name 设置模型的查询名称,用于filter或get查询,若设置参数related_name,则以其为默认值,未设置则使用模型名称的小写为默认值
to_field 设置外键与其他模型字段的关联性,默认关联主键,若关联其他键须保证其唯一性
db_constraint 在数据库里是否创建外键约束默认为True
swappable 设置关联模型的替换功能,默认为True
db_table ManayToManyField,设置表名称
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章