# Django 5.2.8 documentation

# 模型 `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`

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` 管理器名称。

### `default_related_name`

Options.default_related_name

  从相关对象到这个对象的关系默认使用的名称。默认为 `<model_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` 时 唯一 的区别。模型处理的所有其他方面都与正常情况完全相同。这包括

  1. 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.

  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]

  可以通过传递一个 `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`

Options.default_permissions

  默认值为 `('add', 'change', 'delete', 'view')` 。你可以自定义这个列表，例如，如果你的应用不需要任何默认的权限，可以将其设置为空列表。它必须在模型创建之前通过 `migrate` 在模型上指定，以防止任何遗漏的权限被创建。

### `proxy`

Options.proxy

  如果 `proxy = True`，作为另一个模型子类的模型将被视为 代理模型。

### `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 uses `SELECT` to determine if there is an existing row to be updated. The new algorithm tries an `UPDATE` directly. In some rare cases the `UPDATE` of an existing row isn't visible to Django. An example is the PostgreSQL `ON UPDATE` trigger which returns `NULL`. In such cases the new algorithm will end up doing an `INSERT` even 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

  使用 `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(condition=models.Q(age__gte=18), name="age_gte_18"),
              ]

### `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'`。