八、ORM创建表关系

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就是代表当前表

 

posted @ 2021-06-01 10:43  zzwYYYYYY  阅读(106)  评论(0)    收藏  举报