模型Meta选项

本文档解释了所有可能的metadata options,您可以在您的模型的内部 Meta中给出您的模型。

可用Meta选项

abstract

选项。抽象 T0> ¶ T1>

如果摘要 = True,那么这个模型将是一个abstract base class

app_label

选项。 app_label T0> ¶ T1>

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

app_label = 'myapp'

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

base_manager_name

选项。 base_manager_name T0> ¶ T1>

用于模型的_base_manager的经理的名称。

db_table

选项。 db_table T0> ¶ T1>

用于模型的数据库表的名称:

db_table = 'music_album'

表名

为了节省时间,Django自动从模型类的名称和包含它的应用程序中派生出数据库表的名称。 模型的数据库表名是通过将模型的“应用标签”(您在manage.py startapp中使用的名称)类名,在它们之间有一个下划线。

For example, if you have an app bookstore (as created by manage.py startapp bookstore), a model defined as class Book will have a database table named bookstore_book.

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

如果你的数据库表名是一个SQL保留字,或者包含Python变量名中不允许的字符 - 特别是连字符 - 那没问题。 Django在幕后引用列名和表名。

使用MySQL的小写表名

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

Oracle的表名引用

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

db_table = '"name_left_in_lowercase"'

这样的引用名称也可以用于Django的其他支持的数据库后端;除了Oracle之外,引号不起作用。 有关更多详细信息,请参阅Oracle notes

db_tablespace

选项。 db_tablespace T0> ¶ T1>

用于此模型的database tablespace的名称。 默认值是项目的DEFAULT_TABLESPACE设置(如果设置)。 如果后端不支持表空间,则忽略此选项。

default_manager_name

选项。 default_manager_name T0> ¶ T1>

用于模型_default_manager的管理者的名称。

get_latest_by

选项。 get_latest_by T0> ¶ T1>

通常是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()文档。

在Django 2.0中更改:

增加了对字段列表的支持。

managed

选项。管理 T0> ¶ T1>

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

如果False,则不会为此模型执行数据库表创建或删除操作。 如果模型表示已经通过其他方式创建的现有表或数据库视图,那么这非常有用。 managed=False时,这是唯一的区别。 模型处理的所有其他方面与正常情况完全相同。 这包括

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

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

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

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

If you’re interested in changing the Python-level behavior of a model class, you could use managed=False and create a copy of an existing model. 但是,对于这种情况,有更好的方法:Proxy models

order_with_respect_to

选项。 order_with_respect_to T0> ¶ T1>

使这个对象相对于给定的字段成为可订的,通常是一个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])

The related objects also get two methods, get_next_in_order() and get_previous_in_order(), which can be used to access those objects in their proper 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选项设置为该字段。 Consequently, order_with_respect_to and ordering cannot be used together, and the ordering added by order_with_respect_to will apply whenever you obtain a list of objects of this model.

改变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']

您也可以使用query expressions 要按author升序排序并使空值最后排序,请使用以下命令:

from django.db.models import F

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

默认排序也会影响aggregation queries

在Django 2.0中更改:

增加了对查询表达式的支持。

警告

订购不是免费的。 您添加到订单的每个字段都会导致数据库成本。 您添加的每个外键都会隐式地包含其所有默认排序。

如果查询没有指定的顺序,那么结果将从数据库以未指定的顺序返回。 一个特定的顺序只有在通过唯一标识结果中每个对象的一组字段进行排序时才能得到保证。 例如,如果一个name字段不是唯一的,按顺序排列并不能保证具有相同名称的对象总是以相同的顺序出现。

permissions

选项。权限 T0> ¶ T1>

创建此对象时需要额外的权限才能进入权限表。 添加,删除和更改权限是为每个模型自动创建的。 这个例子指定了一个额外的权限,can_deliver_pizzas

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

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

default_permissions

选项。 default_permissions T0> ¶ T1>

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

proxy

选项。代理 T0> ¶ T1>

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

required_db_features

选项。 required_db_features T0> ¶ T1>

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

required_db_vendor

选项。 required_db_vendor T0> ¶ T1>

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

select_on_save

选项。 select_on_save T0> ¶ T1>

Determines if Django will use the pre-1.6 django.db.models.Model.save() algorithm. 旧算法使用SELECT来确定是否存在要更新的现有行。 新算法直接尝试UPDATE 在一些罕见的情况下,Django不会看到现有行的UPDATE 例如PostgreSQL ON UPDATE触发器,它返回NULL 在这种情况下,即使数据库中存在一行,新算法也会执行INSERT

通常不需要设置这个属性。 默认值是False

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

indexes

选项。索引 T0> ¶ T1>
Django 1.11新增功能

您要在模型上定义的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

选项。 unique_together T0> ¶ T1>

字段名称集合在一起必须是唯一的:

unique_together = (("driver", "restaurant"),)

这是元组的元组,当一起考虑时,它们必须是唯一的。 它在Django管理中使用,并在数据库级别执行(即在CREATE TABLE中包含相应的UNIQUE 声明)。

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

unique_together = ("driver", "restaurant")

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

违反约束的模型验证过程中产生的ValidationError具有unique_together错误代码。

index_together

选项。 index_together T0> ¶ T1>

改用indexes选项。

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

字段名称集合在一起编制索引:

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

这个字段列表将一起索引(即,将发布适当的CREATE INDEX语句。)

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

index_together = ["pub_date", "deadline"]

verbose_name

选项。 verbose_name T0> ¶ T1>

对象的人类可读的名字,单数:

verbose_name = "pizza"

如果没有给出,Django将使用一个类名称的老版本:CamelCase变成camel case

verbose_name_plural

选项。 verbose_name_plural T0> ¶ T1>

对象的复数名称:

verbose_name_plural = "stories"

如果没有给出,Django将使用verbose_name + "s"

只读Meta属性

label

选项。标签 T0> ¶ T1>

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

label_lower

选项。 label_lower T0> ¶ T1>

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