模型元选项 — Django 文档
型号 Meta 选项
本文档解释了您可以在其内部 class Meta
中为模型提供的所有可能的 元数据选项 。
可用的 Meta 选项
app_label
- Options.app_label
如果模型是在 :setting:`INSTALLED_APPS` 中的应用程序之外定义的,它必须声明它属于哪个应用程序:
app_label = 'myapp'
如果您想用
app_label.object_name
或app_label.model_name
格式表示模型,您可以分别使用model._meta.label
或model._meta.label_lower
。
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 在幕后引用列名和表名。
Oracle 的表名引用
为了满足 Oracle 对表名的 30 个字符的限制,并匹配 Oracle 数据库的通常约定,Django 可能会缩短表名并将它们全部大写。 为防止此类转换,请使用带引号的名称作为 db_table
的值:
db_table = '"name_left_in_lowercase"'
这种带引号的名称也可以与 Django 其他支持的数据库后端一起使用; 但是,除了 Oracle,引号没有任何作用。 有关更多详细信息,请参阅 Oracle 说明 。
db_tablespace
- Options.db_tablespace
- 用于此模型的 数据库表空间 的名称。 默认是项目的 :setting:`DEFAULT_TABLESPACE` 设置(如果已设置)。 如果后端不支持表空间,则忽略此选项。
get_latest_by
- Options.get_latest_by
模型中的字段名称或字段名称列表,通常为 DateField、DateTimeField 或 IntegerField。 这指定了在模型 Manager 的 latest() 和 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
,则不会对该模型执行任何数据库表创建或删除操作。 如果模型表示现有表或通过其他方式创建的数据库视图,这将非常有用。 这是 only 与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()
,其中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
添加了一个新的数据库列,所以如果您在初始 :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
权限。
required_db_features
- Options.required_db_features
- 当前连接应具有的数据库功能列表,以便在迁移阶段考虑模型。 例如,如果将此列表设置为
['gis_enabled']
,则模型将仅在启用 GIS 的数据库上同步。 在使用多个数据库后端进行测试时跳过某些模型也很有用。 避免可能会或可能不会创建的模型之间的关系,因为 ORM 不处理这个问题。
required_db_vendor
- Options.required_db_vendor
- 此模型特定于的受支持数据库供应商的名称。 当前内置供应商名称为:
sqlite
、postgresql
、mysql
、oracle
。 如果此属性不为空且当前连接供应商不匹配,则不会同步模型。
select_on_save
- Options.select_on_save
确定 Django 是否将使用 1.6 之前的 django.db.models.Model.save() 算法。 旧算法使用
SELECT
来确定是否存在要更新的现有行。 新算法直接尝试UPDATE
。 在极少数情况下,现有行的UPDATE
对 Django 不可见。 一个例子是 PostgreSQLON 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
一组字段名称,它们放在一起必须是唯一的:
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
一组字段名称,它们一起被索引:
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'
。