模型 Meta 选项

本文档解释了您可以在模型的内部 class Meta 中为其提供的所有可能的 元数据选项

可用的 Meta 选项

abstract

Options.abstract

如果 abstract = True,则此模型将成为一个 抽象基类

app_label

Options.app_label

如果模型是在 INSTALLED_APPS 中的应用程序外部定义的,则必须声明它属于哪个应用程序。

app_label = "myapp"

如果要使用 app_label.object_nameapp_label.model_name 格式表示模型,则可以使用 model._meta.labelmodel._meta.label_lower 分别表示。

base_manager_name

Options.base_manager_name

管理器属性名称,例如 'objects',用于模型的 _base_manager

db_table

Options.db_table

要用于模型的数据库表名称。

db_table = "music_album"

表名称

为了节省您的时间,Django 会自动根据模型类的名称和包含它的应用程序派生数据库表名称。模型的数据库表名称是通过将模型的“应用程序标签”(您在 manage.py startapp 中使用的名称)与模型的类名称连接起来,并在它们之间添加一个下划线来构建的。

例如,如果您有一个名为 bookstore 的应用程序(如 manage.py startapp bookstore 创建的那样),定义为 class Book 的模型将具有名为 bookstore_book 的数据库表。

要覆盖数据库表名称,请在 class Meta 中使用 db_table 参数。

如果您的数据库表名称是 SQL 保留字,或者包含 Python 变量名称中不允许的字符(尤其是连字符),则没关系。Django 会在后台为列和表名称加上引号。

对于 MariaDB 和 MySQL,请使用小写表名

强烈建议您在通过 db_table 覆盖表名时使用小写表名,特别是如果您使用的是 MySQL 后端。有关更多详细信息,请参阅 MySQL 说明

Oracle 的表名引用

为了满足 Oracle 对表名 30 个字符的限制,并符合 Oracle 数据库的常用约定,Django 可能会缩短表名并将其全部转换为大写。要防止此类转换,请使用带引号的名称作为 db_table 的值。

db_table = '"name_left_in_lowercase"'

此类带引号的名称也可以与 Django 支持的其他数据库后端一起使用;但是,除了 Oracle 之外,引号没有效果。有关更多详细信息,请参阅 Oracle 说明

db_table_comment

Options.db_table_comment

要用于此模型的数据库表上的注释。它可用于为具有直接数据库访问权限且可能不会查看您的 Django 代码的个人记录数据库表。例如

class Answer(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    answer = models.TextField()

    class Meta:
        db_table_comment = "Question answers"

db_tablespace

Options.db_tablespace

要用于此模型的 数据库表空间 的名称。默认为项目的 DEFAULT_TABLESPACE 设置(如果已设置)。如果后端不支持表空间,则会忽略此选项。

default_manager_name

Options.default_manager_name

要用于模型的 _default_manager 的管理器的名称。

get_latest_by

Options.get_latest_by

模型中字段或字段名称列表的名称,通常为 DateFieldDateTimeFieldIntegerField。这指定了要在模型 Managerlatest()earliest() 方法中使用的默认字段。

示例

# Latest by ascending order_date.
get_latest_by = "order_date"

# Latest by priority descending, order_date ascending.
get_latest_by = ["-priority", "order_date"]

有关更多信息,请参阅 latest() 文档。

managed

Options.managed

默认为 True,这意味着 Django 将在 migrate 中或作为迁移的一部分创建相应的数据库表,并在 flush 管理命令的一部分中删除它们。也就是说,Django 管理数据库表的生命周期。

如果为 False,则不会对该模型执行任何数据库表创建、修改或删除操作。如果模型表示由其他方式创建的现有表或数据库视图,则此选项很有用。这是 managed=False 时的唯一区别。所有其他模型处理方面与正常情况完全相同。这包括

  1. 如果未声明,则向模型添加自动主键字段。为了避免使以后的代码阅读者感到困惑,建议在使用非托管模型时指定要建模的数据库表中的所有列。

  2. 如果一个模型使用 managed=False 并且包含一个指向另一个非托管模型的 ManyToManyField,那么用于多对多连接的中间表也不会被创建。但是,在托管模型和非托管模型之间的中间表 *将* 被创建。

    如果您需要更改此默认行为,请将中间表创建为一个显式模型(并根据需要设置 managed),并使用 ManyToManyField.through 属性使关系使用您的自定义模型。

对于涉及使用 managed=False 的模型的测试,您需要确保作为测试设置的一部分创建了正确的表。

如果您有兴趣更改模型类的 Python 级行为,您可以使用 managed=False 并创建现有模型的副本。但是,对于这种情况,有更好的方法:代理模型

order_with_respect_to

Options.order_with_respect_to

使此对象相对于给定字段(通常是 ForeignKey)可排序。这可用于使相关对象相对于父对象可排序。例如,如果一个 Answer 关联到一个 Question 对象,并且一个问题有多个答案,并且答案的顺序很重要,则执行以下操作

from django.db import models


class Question(models.Model):
    text = models.TextField()
    # ...


class Answer(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    # ...

    class Meta:
        order_with_respect_to = "question"

当设置 order_with_respect_to 时,会提供两种额外的方法来检索和设置相关对象的顺序:get_RELATED_order()set_RELATED_order(),其中 RELATED 是模型名称的小写形式。例如,假设一个 Question 对象有多个相关的 Answer 对象,则返回的列表包含相关 Answer 对象的主键

>>> question = Question.objects.get(id=1)
>>> question.get_answer_order()
[1, 2, 3]

可以通过传入一个 Answer 主键列表来设置 Question 对象的相关 Answer 对象的顺序

>>> question.set_answer_order([3, 1, 2])

相关对象也获得两个方法,get_next_in_order()get_previous_in_order(),它们可用于按正确的顺序访问这些对象。假设 Answer 对象按 id 排序

>>> answer = Answer.objects.get(id=2)
>>> answer.get_next_in_order()
<Answer: 3>
>>> answer.get_previous_in_order()
<Answer: 1>

order_with_respect_to 隐式设置 ordering 选项

在内部,order_with_respect_to 添加一个名为 _order 的额外字段/数据库列,并将模型的 ordering 选项设置为该字段。因此,order_with_respect_toordering 不能一起使用,并且 order_with_respect_to 添加的排序将在您获取此模型的对象列表时始终应用。

更改 order_with_respect_to

因为 order_with_respect_to 添加了一个新的数据库列,所以如果您在初始 migrate 后添加或更改了 order_with_respect_to,请确保进行并应用相应的迁移。

ordering

Options.ordering

对象的默认排序,用于获取对象列表时

ordering = ["-order_date"]

这是一个字符串和/或查询表达式的元组或列表。每个字符串都是一个字段名称,前面可以带有一个可选的“-”前缀,表示降序。没有前导“-”的字段将按升序排序。使用字符串“?”进行随机排序。

例如,要按 pub_date 字段升序排序,请使用以下命令

ordering = ["pub_date"]

要按 pub_date 降序排序,请使用以下命令

ordering = ["-pub_date"]

要按 pub_date 降序排序,然后按 author 升序排序,请使用以下命令

ordering = ["-pub_date", "author"]

您还可以使用 查询表达式。要按 author 升序排序并将空值排序到最后,请使用以下命令

from django.db.models import F

ordering = [F("author").asc(nulls_last=True)]

警告

排序不是一项免费的操作。您添加到排序中的每个字段都会给您的数据库带来成本。您添加的每个外键也将隐式包含其所有默认排序。

如果查询没有指定排序,则结果将以未指定的顺序从数据库返回。只有当按一组唯一标识结果中每个对象的字段排序时,才能保证特定的排序。例如,如果 name 字段不是唯一的,则按它排序不会保证具有相同名称的对象始终以相同的顺序出现。

permissions

Options.permissions

在创建此对象时输入权限表的额外权限。每个模型都会自动创建添加、更改、删除和查看权限。此示例指定了一个额外的权限,can_deliver_pizzas

permissions = [("can_deliver_pizzas", "Can deliver pizzas")]

这是一个格式为 (permission_code, human_readable_permission_name) 的 2 元组列表或元组。

default_permissions

Options.default_permissions

默认为 ('add', 'change', 'delete', 'view')。您可以自定义此列表,例如,如果您的应用程序不需要任何默认权限,则将其设置为空列表。它必须在模型被 migrate 创建之前在模型上指定,以防止创建任何省略的权限。

proxy

Options.proxy

如果 proxy = True,则子类化另一个模型的模型将被视为 代理模型

required_db_features

Options.required_db_features

当前连接应该具有的数据库功能列表,以便在迁移阶段考虑该模型。例如,如果您将此列表设置为 ['gis_enabled'],则该模型将仅在启用 GIS 的数据库上同步。在使用多个数据库后端进行测试时,它也很有用。避免在可能创建也可能不创建的模型之间建立关系,因为 ORM 不会处理这种情况。

required_db_vendor

Options.required_db_vendor

此模型特有的受支持数据库供应商的名称。当前内置的供应商名称为:sqlitepostgresqlmysqloracle。如果此属性不为空且当前连接供应商与之不匹配,则不会同步该模型。

select_on_save

Options.select_on_save

确定 Django 是否将使用 1.6 之前的 django.db.models.Model.save() 算法。旧算法使用 SELECT 来确定是否存在要更新的行。新算法尝试直接执行 UPDATE。在某些罕见情况下,现有行的 UPDATE 对 Django 不可見。一个例子是 PostgreSQL ON UPDATE 触发器,它返回 NULL。在这种情况下,即使数据库中存在行,新算法最终也会执行 INSERT

通常不需要设置此属性。默认值为 False

有关旧版和新版保存算法的更多信息,请参阅 django.db.models.Model.save()

indexes

Options.indexes

要在模型上定义的 索引 列表。

from django.db import models


class Customer(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

    class Meta:
        indexes = [
            models.Index(fields=["last_name", "first_name"]),
            models.Index(fields=["first_name"], name="first_name_idx"),
        ]

unique_together

Options.unique_together

请改用 UniqueConstraintconstraints 选项。

UniqueConstraint 提供比 unique_together 更多的功能。 unique_together 可能会在将来弃用。

字段名称的集合,这些名称组合在一起必须是唯一的。

unique_together = [["driver", "restaurant"]]

这是一个列表的列表,当组合在一起时必须是唯一的。它用于 Django 管理界面,并在数据库级别强制执行(即,在 CREATE TABLE 语句中包含相应的 UNIQUE 语句)。

为了方便起见,当处理单个字段集时,unique_together 可以是单个列表。

unique_together = ["driver", "restaurant"]

ManyToManyField 不能包含在 unique_together 中。(目前尚不清楚这到底意味着什么!)如果您需要验证与 ManyToManyField 相关的唯一性,请尝试使用信号或显式的 through 模型。

当违反约束时,在模型验证期间引发的 ValidationError 具有 unique_together 错误代码。

constraints

Options.constraints

要在模型上定义的 约束 列表。

from django.db import models


class Customer(models.Model):
    age = models.IntegerField()

    class Meta:
        constraints = [
            models.CheckConstraint(condition=models.Q(age__gte=18), name="age_gte_18"),
        ]

verbose_name

Options.verbose_name

对象的易于理解的名称,单数形式。

verbose_name = "pizza"

如果未提供,Django 将使用类名称的修改版本:CamelCase 将变为 camel case

verbose_name_plural

Options.verbose_name_plural

对象的复数名称。

verbose_name_plural = "stories"

如果未提供,Django 将使用 verbose_name + "s"

只读 Meta 属性

label

Options.label

对象的表示形式,返回 app_label.object_name,例如 'polls.Question'

label_lower

Options.label_lower

模型的表示形式,返回 app_label.model_name,例如 'polls.question'

返回顶部