django
模型间的关系分为多对一
,一对一
,多对多
一、多对一
关系
1.1 创建多对一
模型model
通过ForeignKey
可以实现django
的多对一关系关联,
class ForeignKey( to, on_delete, related_name=None, related_query_name=None,
limit_choices_to=None, parent_link=False, to_field=None,
db_constraint=True, **kwargs)
其中两个位置参数to
, on_delete
为必须传入的参数
from django.db import models
class Author(models.Model):
username = models.CharField('作者', max_length = 32)
class Article(models.Model):
title = models.CharField(max_length=64)
content = models.TextField()
# 关联`Author`类
author = models.ForeignKey(
Author,
on_delete=models.CASCADE # 这里先这么进行设置
)
如果需要在尚未定义的模型上创建关系,则可以使用模型的名称,而不是模型对象本身:
class Article(models.Model):
title = models.CharField(max_length=64)
content = models.TextField()
author = models.ForeignKey(
'Author',
on_delete=models.CASCADE
)
class Author(models.Model):
username = models.CharField('作者', max_length=32)
上述完成了将Article
- Author
关联成多对一
关系。
1.2 多对一
模型之间访问
-
正向访问
在上面模型关系中,Article
拥有一个author
属性,该属性实际存储了Author
的id
,我们可以通过.author
获取Author
对象。
二、模型关系的参数设置
-
on_delete
表示删除外键时,引起sql
行为.
on_delete
可以为以下值,它们都可以从django.db.models
导入:
-
CASCADE
: 表示联级删除。
例如在上述Article
中,我们设置on_delete=models.CASCADE
这表示当我们删除某一个Author
对象时,该Author
对象反向关联的所有Article
数据将被django
自动删除。这是为了防止产生无意义数据
。
因为在很多多对一关系对象
中,我们并不直接访问Article
,而是通过Author
来间接访问Article
,当我们删除Author
时,也就表示不再访问Article
,这个时候也应该随之将Article
,否则就会产生无法访问的脏数据
, CASCADE
约束就是为了防止我们忘记删除关联的数据,特别是当多个数据表关联了该ForeignKey
。
建议谨慎使用CASCADE
。
-
PROTECT
: 通过引发ProtectedError
来防止删除引用的对象
设置on_delete = CASCADE
后,将由django
自动帮我们进行删除,且没有提醒,我们会觉得这有一定的风险,Author
关联的Article
是否都是没有用的呢?是不是要留下一些呢?
PROTECT
在删除ForeignKey
前会检查被关联的对象是否都已经被删除,如果没有就会引起ProtectedError
异常。这就需要我们手动删除关联的对象后,再删除ForeignKey
对象。
def delete_ Author(pk):
author = Author.objects.get(pk=pk)
# 手动删除 articles
articles = author.article_set.all()
for article in articels:
article.delete()
author.delete()
-
SET_NULL
允许我们删除ForeignKey
对象,且删除后会保留相关联的对象,并将ForeignKey
设置为null
class Article(models.Model):
title = models.CharField(max_length=64)
content = models.TextField()
author = models.ForeignKey(
'Author',
on_delete=models.CASCADE,
null=True # 必须设置
)
只有当on_delete=SET_NULL
时,才能设置null=True
-
SET_DEFAULT
将ForeignKey
设置为默认值,此时必须设置default
属性,这里表示删除指定Author
对象后,该Author
对象相关联的Article
将author
设置为默认值。
例如用户注销账号后,用户的评论信息
保留,在个时候用户名显示该用户已注销
,就是我们的删除用户后设置的默认用户。 -
SET()
在SET_DEFAULT
中,默认值是固定的,但是很多时候我们的默认值可能是在变化的,使用SET()
可以传递callable
,调用它的结果赋值给设置ForeignKey
的字段
def get_first_author():
return Author.objects.all().first()
class Article(models.Model):
title = models.CharField(max_length=64)
content = models.TextField()
author = models.ForeignKey(
'Author',
on_delete=models.SET(get_first_author),
)
-
DO_NOTHING
什么都不做,不采取行动。
网友评论