模型一对多关联关系学习笔记

每个模型都继承自django.db.model.Model
模型类的每个属性都相当于一个数据库的字段
数据库表名默认为 应用名 + _ + 模型类小写,例如bookstory 应用中的模型Book,数据库对应的表名默认为 bookstory_book,可以通过Meta 中的db_table参数覆盖数据库表名

字段通用选项

  • null 如果设置为True,当字段为空时,Django会将数据库中该字段设置为NULL。默认为False
  • blank 如果设置为True,该字段允许为空,默认为False。与null选项不同的是,null选项是数据库层面的设置,而blank涉及表单验证。如果一个字段设置为blank=True,在进行表单验证时,接收的数据该字段允许为空,否则不允许为空
  • choice 一系列二元组,用做此字段的选项。如果提供了二元组,默认表单小组件是一个选择框,而不是标准的文本字段,并将限制给出的选项。每当choice的顺序变动时,将创建新的迁移
  • default 默认值。可以是一个值或者是个可调用对象,如果是可调用对象,每次实例化模型时都会调用该对象
  • help_text 额外的帮助文本,随表单控件一同显示。对于生成文档很有帮助
  • primary_key 如果设置为True,该字段为该模型主键
  • unique 如果设置为True,这个字段的值必须在整个表中保持唯一

关联关系

Django 提供了定义三种最常见的数据库关联关系的方法:多对一,多对多,一对一

多对一关联

使用django.db.models.ForeignKey定义多对一关联关系。

参数

  • on_delete 约束被引用对象删除时的行为,不会在数据库中创建sql约束

CASCADE 级联删除。Django模拟了SQL约束 ON DELETE CASCADE 的行为,也删除了包含ForeignKey的对象。通过pre_delete 和 post_delete 信号删除相关对象
PROTECT 通过引发 ProtectedError,防止被删除的对象
RESTRICT 通过引发 RestrictedError 来防止删除被引用的对象。与PROTECT不同的是,如果被引用的对象通过CASCADE关系也引用了一个在同一操作中被删除的不同对象,则允许删除被引用的对象
SET_NULL 设置ForeignKey 为空;只有当null为True时,才可以
SET_DEFAULT 将ForeignKey设置为默认值
SET() 将ForeignKey设置为传递给SET()的值
DO_NOTHING 不采取任何行动

class Artist(models.Model):
    name = models.CharField(max_length=10)

class Album(models.Model):
    artist = models.ForeignKey(Artist, on_delete=models.CASCADE)

class Song(models.Model):
    artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
    album = models.ForeignKey(Album, on_delete=models.RESTRICT)

>>> artist_one = Artist.objects.create(name='artist one')
>>> artist_two = Artist.objects.create(name='artist two')
>>> album_one = Album.objects.create(artist=artist_one)
>>> album_two = Album.objects.create(artist=artist_two)
>>> song_one = Song.objects.create(artist=artist_one, album=album_one)
>>> song_two = Song.objects.create(artist=artist_one, album=album_two)
>>> album_one.delete()     # 因为song_one 通过RESTRICT方式引用着album_one,所以不允许删除
# Raises RestrictedError.
>>> artist_two.delete()   # 级联删除时,因为song_two 通过RESTRICT方式引用着album_two,所以不允许删除
# Raises RestrictedError.
>>> artist_one.delete()   # 级联删除时,虽然artist_one 通过RESTRICT方式引用着album_one,但是album_one通过CASCADE方式引用artist_one,且刚好要删除artist_one,所以允许删除
(4, {'Song': 2, 'Album': 1, 'Artist': 1})    # 级联删除成功,共删除四条数据,artist_one, artist_two, album_one, artist_one
  • limit_choices_to 当ModelForm 或者管理中渲染该字段时,设置该字段的可用选择限制
staff_member = models.ForeignKey(
    User,
    on_delete=models.CASCADE,
    limit_choices_to={'is_staff': True},
)
  • related_name 用于相关对象到这个对象的关系的名称。这也是related_query_name的默认值。

如果不希望Django创建一个反向关系,可以将related_name设置为 ‘+’或者以‘+’结束,例如,这将确保User模型不会与这个模型有反向关系

user = models.ForeignKey(
    User,
    on_delete=models.CASCADE,
    related_name='+',
)
  • related_query_name 目标模型中反向过滤器的名称,如果设置了,它默认为related_name或者default_related_name的值,否则默认为模型的名称:
# Declare the ForeignKey with related_query_name
class Tag(models.Model):
    article = models.ForeignKey(
        Article,
        on_delete=models.CASCADE,
        related_name="tags",
        related_query_name="tag",
    )
    name = models.CharField(max_length=255)

# That's now the name of the reverse filter
Article.objects.filter(tag__name="important")
  • to_field 关联对象的字段。默认情况下,Django使用相关对象的主键。如果引用其他字段,字段类型必须为unique=True
  • db_constraint 控制是否应该在数据库中为这个外键创建一个约束。默认为True。设置为False,访问一个不存在的对象将引发DoseNotExist异常

posted on 2022-12-02 22:15  每日问答  阅读(61)  评论(0)    收藏  举报

导航