模型 Meta 选项¶
本文档解释了所有可能的 元数据选项,你可以在模型的内部 class Meta 中为模型提供这些选项。
可用的 Meta 选项¶
abstract¶
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¶
- Options.db_table¶
用于模型的数据库表的名称:
db_table = "music_album"
表名称¶
为了节省你的时间,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_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¶
模型中的字段名或字段名列表,通常是
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时 唯一 的区别。模型处理的所有其他方面都与正常情况完全相同。这包括Adding an automatic primary key field to the model if you don't declare it. To avoid confusion for later code readers, it's recommended to specify all the columns from the database table you are modeling when using unmanaged models.
如果一个带有
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_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)]
Default ordering and GROUP BY
In GROUP BY queries (for example,
those using values() and annotate()), the
default ordering is not applied.
Warning
排序不是一个免费的操作。你添加到排序中的每个字段都会给你的数据库带来成本。你添加的每个外键都会隐式地包含其所有的默认排序。
如果查询没有指定顺序,那么结果将以未指定的顺序从数据库中返回。只有当按一组字段排序时,才能保证特定的排序,这些字段唯一地标识结果中的每个对象。例如,如果 name 字段不是唯一的,那么按它排序就不能保证具有相同名称的对象总是以相同的顺序出现。
permissions¶
- Options.permissions¶
创建此对象时要输入权限表的额外权限。为每个模型自动创建添加、更改、删除和查看权限。这个例子指定了一个额外的权限,
can_deliver_pizzas:permissions = [("can_deliver_pizzas", "Can deliver pizzas")]
这是一个由二元元组组成的列表或元组,格式为
(permission_code, human_readable_permission_name)。
default_permissions¶
proxy¶
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¶
Determines if Django will use the pre-1.6
django.db.models.Model.save()algorithm. The old algorithm usesSELECTto determine if there is an existing row to be updated. The new algorithm tries anUPDATEdirectly. In some rare cases theUPDATEof an existing row isn't visible to Django. An example is the PostgreSQLON UPDATEtrigger which returnsNULL. In such cases the new algorithm will end up doing anINSERTeven when a row exists in the database.通常不需要设置这个属性。默认值是
False。See
django.db.models.Model.save()for more about the old and new saving algorithm.
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¶
-
一组字段名,合起来必须是唯一的:
unique_together = [["driver", "restaurant"]]
这是一个列表,这些列表在一起考虑时必须是唯一的。它 在Django 管理中使用,并在数据库级别执行(即在
CREATE TABLE语句中包含适当的UNIQUE语句)。为方便起见,
unique_together在处理单组字段时可以是一个单一的列表:unique_together = ["driver", "restaurant"]
ManyToManyField不能包含在unique_together中。(甚至不清楚这意味着什么!)如果需要验证与ManyToManyField相关的唯一性,请尝试使用信号或显式的through模型。在模型验证过程中,当约束条件被违反时引发的
ValidationError具有unique_together错误代码。
constraints¶
verbose_name¶
- Options.verbose_name¶
对象的可读名称,单数:
verbose_name = "pizza"
如果没有给定,Django 将使用一个 munged 版本的类名:
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'。