Meta
选项
本文档解释了所有可能的 元数据选项,你可以在模型的内部 class Meta
中为模型提供这些选项。
可用的 Meta
选项
abstract
-
Options.
abstract
如果
abstract = True
,这个模型将是一个 抽象基类。
app_label
-
Options.
app_label
如果在
INSTALLED_APPS
中定义了一个应用程序之外的模型,它必须声明它属于哪个应用程序:app_label = 'myapp'
如果你想用
app_label.object_name
或app_label.model_name
来表示一个模型,你可以分别使用model._meta.label
或model._meta.label_lower
。
base_manager_name
-
Options.
base_manager_name
管理器的属性名,例如,
'objects'
,用于模型的_base_manager
。
db_table
表名称
为了节省你的时间,Django 会自动从你的模型类和包含它的应用程序的名称中导出数据库表的名称。一个模型的数据库表名是通过将模型的“app label”——你在 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_tablespace
-
Options.
db_tablespace
此模型要使用的 数据库表空间 名称。如果有设置的话,默认是项目的
DEFAULT_TABLESPACE
配置。如果后端不支持表空间,则忽略此选项。
default_manager_name
-
Options.
default_manager_name
模型的
_default_manager
管理器名称。
default_related_name
-
Options.
default_related_name
从相关对象到这个对象的关系默认使用的名称。默认为
_set
。这个选项还可以设置
related_query_name
。由于字段的反向名称应该是唯一的,所以如果你打算对你的模型进行子类化,就要小心了。为了避免名称冲突,名称的一部分应该包含
'%(app_label)s'
和'%(model_name)s'
,它们分别被模型所在的应用程序的名称和模型的名称所取代,都是小写的。见 抽象模型的相关名称 段落。
get_latest_by
-
Options.
get_latest_by
模型中的字段名或字段名列表,通常是
DateField
,DateTimeField
或IntegerField
。这指定了在你的模型中使用的默认字段Manager
的last()
和earliest()
方法。举例:
# Latest by ascending order_date. get_latest_by = "order_date" # Latest by priority descending, order_date ascending. get_latest_by = ['-priority', 'order_date']
更多内容请参见
last()
文档。
managed
-
Options.
managed
默认为
True
,意味着 Django 会在migrate
中创建相应的数据库表,或者作为迁移的一部分,并作为flush
管理命令的一部分删除它们。也就是说,Django 管理 数据库表的生命周期。如果
False
,将不对该模型进行数据库表的创建、修改或删除操作。如果该模型代表一个现有的表或一个通过其他方式创建的数据库视图,这一点很有用。这是在managed=False
时 唯一 的区别。模型处理的所有其他方面都与正常情况完全相同。这包括如果不声明的话,在模型中增加一个自动主键字段。 为了避免给后面来的代码读者带来困惑,建议在使用非托管模型时,指定你所建模的数据库表的所有列。
如果一个带有
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()
。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_to
和 ordering
不能同时使用,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
字段不是唯一的,那么按它排序就不能保证具有相同名称的对象总是以相同的顺序出现。
default_permissions
-
Options.
default_permissions
默认值为
('add', 'change', 'delete', 'view')
。你可以自定义这个列表,例如,如果你的应用不需要任何默认的权限,可以将其设置为空列表。它必须在模型创建之前通过migrate
在模型上指定,以防止任何遗漏的权限被创建。
proxy
-
Options.
proxy
如果
proxy = True
,作为另一个模型子类的模型将被视为 代理模型。
select_on_save
-
Options.
select_on_save
确定 Django 是否会使用 1.6 之前的
django.db.models.Model.save()
算法。旧的算法使用SELECT
来确定是否有一条现有的记录需要更新。新算法直接尝试UPDATE
。在一些罕见的情况下,Django 看不到现有行的UPDATE
。例如 PostgreSQL 的ON UPDATE
触发器会返回NULL
。在这种情况下,即使数据库中存在一条记录,新算法最终也会进行INSERT
。通常不需要设置这个属性。默认值是
False
。关于新旧保存算法,请参见
django.db.models.Model.save()
。
indexes
-
Options.
indexes
你想在模型上定义的 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
使用
UniqueConstraint
与constraint
选项代替。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(check=models.Q(age__gte=18), name='age_gte_18'), ]
verbose_name_plural
-
Options.
verbose_name_plural
对象的复数名称:
verbose_name_plural = "stories"
如果没有给定,Django 将使用
verbose_name
+"s"
。
讨论区