ORM创建表关系
'''
在django1.X版本中外键默认都是级联更新删除的
表与表之间的关系一般有四种:
一对一
一对多
多对多
没有关系
建立表关系时,外键字段创建位置:
一对多:一
一对一:常用方
多对多:常用方
'''
OneToOneField:一对一
class 类名(model.Model):
变量名 = models.OneToOneField(to='对端表类名')
'''
该语法会在本表内创建一个 "变量名_id" 的字段,用来存储与对端表的关联关系
PS:如果手动在 变量名 后加了 _id 那么orm 还会在变量名后加 _id
注意:
1. 改语法需要写在表对应的python类中
2. 建议该语法所在表是一对一中被查询最频繁的
参数介绍:
1. to:本表需要做外键关联的对端表名
2. to_field:该参数可以不写,默认就是和指定表中的主键字段做外键关联
'''
ForeignKey:一对多
class 类名(model.Model):
变量名 = models.ForeignKey(to='对端表类名',to_field='id')
'''
该语法会在本表内创建一个 "变量名_id" 的字段,用来存储与对端表的关联关系
PS:如果手动在 变量名 后加了 _id 那么orm 还会在变量名后加 _id
注意:
1. 该语法需要写在表对应的python类中
2. 建议该语法所在表是一对多中的多
参数介绍:
1. to:本表需要做外键关联的对端表名
2. to_field:该参数可以不写,默认就是和指定表中的主键字段做外键关联
'''
ManyToManyField:多对多
1、全自动
class 类名(model.Model):
变量名 = models.ManyToManyField(to='对端表类名',to_file='id')
'''
该代码是一个虚拟字段,主要是用来告诉orm,本表与对端表是多对多关系
全自动:让orm自动帮你创建第三张关系表
优点:
代码不需要你写,非常的方便
还支持orm提供操作第三张关系表的方法...
不足之处:
第三张关系表的扩展性极差(没有办法额外添加字段...)
注意:
1. 改语法需要写在表对应的python类中
2. 建议该语法所在表是多对多中被查询最频繁的
参数介绍:
1. to:本表需要做外键关联的对端表名
2. to_field:该参数可以不写,默认就是和指定表中的主键字段做外键关联
'''
2、纯手动
class 类名1(models.Model):
变量名 = models.字段名(字段参数)
class 类名2(models.Model):
变量名 = models.字段名(字段参数)
class 类名3(models.Model):
类名1小写_id = models.ForeignKey(to='类名1')
类名2小写_id = models.ForeignKey(to='类名2')
'''
优点:
第三张表完全取决于你自己进行额外的扩展
不足之处:
需要写的代码较多,不能够再使用orm提供的简单的方法
不建议你用该方式
'''
3、半自动
class 类名1(models.Model):
变量名 = models.字段名(字段参数)
外键名 = models.ManyToManyField(
to='类名2',
through='关系表名',
through_fields=('类名1小写','类名2小写')
)
class 类名2(models.Model):
变量名 = models.字段名(字段参数)
class 关系表名(models.Model):
类名1小写 = models.ForeignKey(to='类名1')
类名2小写 = models.ForeignKey(to='类名2')
'''
参数介绍:
1. through:告诉ORM不需要再自动创建关系表,使用当前指定的关系表即可
2. through_fileds:告诉ORM 类名1表 是通过关系表中的那些字段,与 类名2表 建立关系
('类名1小写','类名2小写')内部书写顺序,当外键存在于那个表,则将当前表放在第一位书写即可
注意:
1. 半自动,可以使用orm的正反向查询
2. 半自动,没法使用add,set,remove,clear这四个方法
总结:你需要掌握的是全自动和半自动,为了扩展性更高,一般我们都会采用半自动(写代码要给自己留一条后路)
'''
OneToOneField参数
to
class 类名(model.Model):
变量名 = models.OneToOneField(to='对端表类名')
'''
to:本表需要做外键关联的对端表名
'''
to_field
class 类名(model.Model):
变量名 = models.OneToOneField(to_file='id')
'''
to_field:该参数可以不写,默认就是和指定表中的主键字段做外键关联
'''
on_delete
class 类名(model.Model):
变量名 = models.OneToOneField(on_delete=函数名)
'''
当删除关联表中的数据时,当前表与其关联的行的行为。
'''
ForeignKey参数
其他models参数
'''
models.DO_NOTHING
删除关联数据,引发错误IntegrityError
models.PROTECT
删除关联数据,引发错误ProtectedError
models.SET_NULL
删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
models.SET_DEFAULT
删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
models.SET
删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
to
class 类名(model.Model):
变量名 = models.ForeignKey(to='对端表类名')
'''
to:本表需要做外键关联的对端表名
'''
to_field
class 类名(model.Model):
变量名 = models.ForeignKey(to_file='id')
'''
to_field:该参数可以不写,默认就是和指定表中的主键字段做外键关联
'''
on_delete
class 类名(model.Model):
变量名 = models.ForeignKey(on_delete=函数名)
'''
当删除关联表中的数据时,当前表与其关联的行的行为。
'''
models.CASCADE
class 类名(model.Model):
变量名 = models.ForeignKey(models.CASCADE())
'''
删除关联数据,与之关联也删除
'''
db_constraint
class 类名(model.Model):
变量名 = models.ForeignKey(db_constraint=True)
'''
是否在数据库中创建外键约束,默认为True。
'''
PS:ORM自关联
'''
存在一种情况,一个表自己与自己存在关联关系
例如,评论表
记录哪个用户给哪篇文章写了哪些评论内容
user ForeignKey(to="User")
article ForeignKey(to="Article")
content CharField()
comment_time DateField()
此刻,该表可以清晰的记录那个用户给那篇文章写了那些评论
但是,如果该用户写的评论,被第二个用户回复呢?
根评论
根评论就是直接评论当前发布的内容的
子评论
子评论是评论别人的评论
A:PHP是世界上最牛逼的语言
B->A:python才是最牛逼的
C->B:java才是
由此可见,根评论与子评论是一对多关系
在上述情况下,对于同一张评论表,我们还需要设置自己关联自己
当某个用户对另一个用户评论进行回复时,创建一个字段,该字段用于存储根评论的key_id,证明该用户是对此用户评论进行子评论
'''
from django.db import models
class Comment(models.Model):
user = models.ForeignKey(to="User")
article = models.ForeignKey(to="Article")
content = models.CharField()
comment_time = models.DateField()
# 自关联写法
parent = models.ForeignKey(to="Comment",null=True)
# ORM专门提供的自关联写法
parent = ForeignKey(to="self",null=True)
# self就是代表当前表