模型元选项 — Django 文档

来自菜鸟教程
Django/docs/2.2.x/ref/models/options
跳转至:导航、​搜索

型号 Meta 选项

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

可用的 Meta 选项

abstract

Options.abstract
如果abstract = True,这个模型将是一个抽象基类


app_label

Options.app_label

如果模型是在 :setting:`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 会自动从您的模型类和包含它的应用程序的名称中派生出数据库表的名称。 模型的数据库表名称是通过加入模型的“应用程序标签”(您在其中使用的名称)构建的 :djadmin:`manage.py startapp ` – 到模型的类名,它们之间有下划线。

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

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

如果您的数据库表名是 SQL 保留字,或者包含 Python 变量名中不允许的字符(尤其是连字符),那也没关系。 Django 在幕后引用列名和表名。

对 MySQL 使用小写表名

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


Oracle 的表名引用

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

db_table = '"name_left_in_lowercase"'

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


db_tablespace

Options.db_tablespace
用于此模型的 数据库表空间 的名称。 默认是项目的 :setting:`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 将在 :djadmin:`migrate` 或作为迁移的一部分创建适当的数据库表,并作为 :djadmin:`flush 的一部分删除它们` 管理命令。 也就是说,Django 管理 数据库表的生命周期。

如果为False,则不会对该模型执行任何数据库表创建或删除操作。 如果模型表示现有表或通过其他方式创建的数据库视图,这将非常有用。 这是 onlymanaged=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]

Question 对象的相关 Answer 对象的顺序可以通过传入 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 添加了一个新的数据库列,所以如果您在初始 :djadmin:`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)]

默认排序也会影响 聚合查询 ,但从 Django 3.1 开始就不会出现这种情况。

警告

订购不是免费的操作。 您添加到排序中的每个字段都会对您的数据库产生成本。 您添加的每个外键也将隐式包含其所有默认排序。

如果查询未指定排序,则以未指定的顺序从数据库返回结果。 只有在按唯一标识结果中每个对象的一组字段进行排序时,才能保证特定的排序。 例如,如果 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')。 您可以自定义此列表,例如,如果您的应用不需要任何默认权限,则将其设置为空列表。 :djadmin:`migrate` 创建模型之前,必须在模型上指定它,以防止创建任何省略的权限。

2.1 版更改: 添加了 view 权限。


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 管理员中使用并在数据库级别强制执行(即,适当的 UNIQUE 语句包含在 CREATE TABLE 语句中)。

为方便起见,在处理一组字段时, unique_together 可以是单个列表:

unique_together = ['driver', 'restaurant']

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

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


index_together

Options.index_together

请改用 indexes 选项。

较新的 indexes 选项提供了比 index_together 更多的功能。 index_together 将来可能会被弃用。

一组字段名称,它们一起被索引:

index_together = [
    ["pub_date", "deadline"],
]

这个字段列表将被一起索引(即 将发布相应的 CREATE INDEX 声明。)

为方便起见,在处理一组字段时, index_together 可以是单个列表:

index_together = ["pub_date", "deadline"]


constraints

Options.constraints

2.2 版中的新功能。

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

from django.db import models

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

    class Meta:
        constraints = [
            models.CheckConstraint(check=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'