学习资料
《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)
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)
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:第三张表在执行迁移和生成命令时自动生成在数据库中
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,设置表名称 |