django 模型关系

2020-03-05  本文已影响0人  eeert2

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 多对一模型之间访问
  1. 正向访问
    在上面模型关系中,Article拥有一个author属性,该属性实际存储了Authorid,我们可以通过.author获取Author对象。

二、模型关系的参数设置

  1. CASCADE : 表示联级删除。

例如在上述Article中,我们设置on_delete=models.CASCADE
这表示当我们删除某一个Author对象时,该Author对象反向关联的所有Article数据将被django自动删除。这是为了防止产生无意义数据

因为在很多多对一关系对象中,我们并不直接访问Article,而是通过Author来间接访问Article,当我们删除Author时,也就表示不再访问Article,这个时候也应该随之将Article,否则就会产生无法访问的脏数据, CASCADE约束就是为了防止我们忘记删除关联的数据,特别是当多个数据表关联了该ForeignKey

建议谨慎使用CASCADE

  1. 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()
  1. 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

  1. SET_DEFAULT
    ForeignKey设置为默认值,此时必须设置default属性,这里表示删除指定Author对象后,该Author对象相关联的Articleauthor设置为默认值。
    例如用户注销账号后,用户的评论信息保留,在个时候用户名显示该用户已注销,就是我们的删除用户后设置的默认用户。

  2. 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),
    )
  1. DO_NOTHING 什么都不做,不采取行动。
上一篇 下一篇

猜你喜欢

热点阅读