---
title: "模型字段参考"
version: 5.2
locale: zh-hans
source: https://docs.djangoproject.com/zh-hans/5.2/ref/models/fields/
canonical: https://djangodocs.dev/zh-hans/5.2/ref/models/fields/
---
# 模型字段参考

本文档包含 [`Field`](#django.db.models.Field) 类的所有 API 参考，包括 [字段选项](#field-options) 和 [字段类型](#field-types)。

> **See also**
>
> 如果内置字段不能满足需求，你可以尝试 [django-localflavor](https://pypi.org/project/django-localflavor/) ([文档](https://django-localflavor.readthedocs.io/))，它包含了对特定国家和文化有用的各种代码片段。
>
> 当然，你也可以简单的 [编写自定义模型字段](/zh-hans/5.2/howto/custom-model-fields/)。

> **Note**
>
> 字段定义在 [`django.db.models.fields`](#module-django.db.models.fields) 中，但为了方便，它们被导入到 [`django.db.models`](/zh-hans/5.2/topics/db/models/#module-django.db.models) 中。标准约定是使用 `from django.db import models` 并将字段引用为 `models.<Foo>Field`。

## 字段选项

以下参数对所以字段类型均有效，且是可选的。

### `null`

#### `Field.null`

如果是 `True`， Django 将在数据库中存储空值为 `NULL`。默认为 `False`。

Avoid using [`null`](#django.db.models.Field.null) on string-based fields such as
[`CharField`](#django.db.models.CharField) and [`TextField`](#django.db.models.TextField). The Django convention is to use an
empty string, not `NULL`, as the "no data" state for string-based fields. If a
string-based field has `null=False`, empty strings can still be saved for "no
data". If a string-based field has `null=True`, that means it has two possible
values for "no data": `NULL`, and the empty string. In most cases, it's
redundant to have two possible values for "no data". One exception is when a
[`CharField`](#django.db.models.CharField) has both `unique=True` and `blank=True` set. In this
situation, `null=True` is required to avoid unique constraint violations when
saving multiple objects with blank values.

无论是基于字符串的字段还是非字符串的字段，如果希望在表单中允许空值，还需要设置 `blank=True`，因为 [`null`](#django.db.models.Field.null) 参数只影响数据库的存储（参见 [`blank`](#django.db.models.Field.blank) ）。

> **Note**
>
> 当使用 Oracle 数据库后端时，不管这个属性是什么，都会存储 `NULL` 值来表示空字符串。

### `blank`

#### `Field.blank`

如果是 `True` ，该字段允许为空。默认为 `False` 。

注意，这与 [`null`](#django.db.models.Field.null) 不同。 [`null`](#django.db.models.Field.null) 纯属数据库相关，而 [`blank`](#django.db.models.Field.blank) 则与验证相关。如果一个字段有 `blank=True`，表单验证将允许输入一个空值。如果一个字段有 `blank=False`，则该字段为必填字段。

> **提供缺失值**
>
> `blank=True` 可以用于 `null=False` 的字段，但这需要在模型上实现 [`clean()`](/zh-hans/5.2/ref/models/instances/#django.db.models.Model.clean)，以便以编程方式提供任何缺失值。

### `choices`

#### `Field.choices`

一个以下述格式的映射或可迭代对象，用作该字段的选项。如果提供了选项，它们将被 [模型验证](/zh-hans/5.2/ref/models/instances/#validating-objects) 强制执行，并且默认的表单小部件将是一个选择框，其中包含这些选项，而不是标准的文本字段。

如果提供了映射，键元素是要设置在模型上的实际值，第二个元素是可读的人类名称。例如：

```
YEAR_IN_SCHOOL_CHOICES = {
    "FR": "Freshman",
    "SO": "Sophomore",
    "JR": "Junior",
    "SR": "Senior",
    "GR": "Graduate",
}
```

你还可以传递一个包含自身由两个项目的可迭代对象的 序列 （例如，`[(A1, B1), (A2, B2), …]`）。每个元组中的第一个元素是要设置在模型上的实际值，第二个元素是可读的人类名称。例如：

```
YEAR_IN_SCHOOL_CHOICES = [
    ("FR", "Freshman"),
    ("SO", "Sophomore"),
    ("JR", "Junior"),
    ("SR", "Senior"),
    ("GR", "Graduate"),
]
```

`choices` 也可以定义为一个可调用对象，它不需要参数并返回上述任何格式之一。例如：

```
def get_currencies():
    return {i: i for i in settings.CURRENCIES}

class Expense(models.Model):
    amount = models.DecimalField(max_digits=10, decimal_places=2)
    currency = models.CharField(max_length=3, choices=get_currencies)
```

当选项是以下情况时，将可调用对象传递给 `choices` 可以特别方便：

- 将可调用对象传递给 `choices` 尤其方便的情况是，它可以用于处理 I/O 绑定的操作结果（这些结果可能会被缓存），比如查询同一数据库或外部数据库中的表，或者从静态文件中获取选项。
- 一个大部分稳定但在不同时间或项目之间可能会有变化的列表。这种情况下的示例包括使用第三方应用程序，这些应用程序提供了已知的值清单，如货币、国家、语言、时区等。

一般来说，最好在模型类内部定义选择，并为每个值定义一个合适的名称的常量：

```
from django.db import models

class Student(models.Model):
    FRESHMAN = "FR"
    SOPHOMORE = "SO"
    JUNIOR = "JR"
    SENIOR = "SR"
    GRADUATE = "GR"
    YEAR_IN_SCHOOL_CHOICES = {
        FRESHMAN: "Freshman",
        SOPHOMORE: "Sophomore",
        JUNIOR: "Junior",
        SENIOR: "Senior",
        GRADUATE: "Graduate",
    }
    year_in_school = models.CharField(
        max_length=2,
        choices=YEAR_IN_SCHOOL_CHOICES,
        default=FRESHMAN,
    )

    def is_upperclass(self):
        return self.year_in_school in {self.JUNIOR, self.SENIOR}
```

虽然你可以在模型类之外定义一个选择列表，然后引用它，但在模型类内定义选择和每个选择的名称，可以将所有这些信息保留在使用它的类中，并帮助引用这些选择（例如，`Student.SOPHOMORE` 将在导入 `Student` 模型的任何地方工作）。

你还可以将你的可用选择收集到可用于组织目的的命名组中：

```
MEDIA_CHOICES = {
    "Audio": {
        "vinyl": "Vinyl",
        "cd": "CD",
    },
    "Video": {
        "vhs": "VHS Tape",
        "dvd": "DVD",
    },
    "unknown": "Unknown",
}
```

映射的键是要应用于组的名称，值是该组内的选项，包括字段值和一个可读的选项名称。在单个映射内，可以将分组选项与非分组选项组合在一起（例如，此示例中的 `"unknown"` 选项）。

你还可以使用一个序列，例如，一个包含 2 元组的列表：

```
MEDIA_CHOICES = [
    (
        "Audio",
        (
            ("vinyl", "Vinyl"),
            ("cd", "CD"),
        ),
    ),
    (
        "Video",
        (
            ("vhs", "VHS Tape"),
            ("dvd", "DVD"),
        ),
    ),
    ("unknown", "Unknown"),
]
```

请注意，选择可以是任何序列对象——不一定是列表或元组。这让你可以动态地构造选择。但是如果你发现自己把 `chips` 魔改成动态的，你可能最好使用一个合适的的带有 [`ForeignKey`](#django.db.models.ForeignKey) 的数据库表。 `chips` 是用于静态数据的，如果有的话，不应该有太大的变化。

> **Note**
>
> 每当 `choices` 的顺序变动时将会创建新的迁移。

对于每个具有 [`choices`](#django.db.models.Field.choices) 设置的模型字段，Django 将规范化选择项为一个 2-元组的列表，并添加一个方法来获取字段当前值的可读名称。请参阅数据库 API 文档中的 [`get_FOO_display()`](/zh-hans/5.2/ref/models/instances/#django.db.models.Model.get_FOO_display)。

除非 [`blank=False`](#django.db.models.Field.blank) 与 [`default`](#django.db.models.Field.default) 一起设置在字段上，否则包含 `"---------"` 的标签将与选择框一起呈现。要覆盖这种行为，可以在 `choices` 中添加一个包含 `None` 的元组，例如 `(None, 'Your String For Display')` 。另外，你也可以在有意义的地方使用一个空字符串来代替 `None` ——比如在 [`CharField`](#django.db.models.CharField)。

#### 枚举类型

此外，Django 还提供了枚举类型，你可以通过将其子类化来简洁地定义选择：

```
from django.utils.translation import gettext_lazy as _

class Student(models.Model):
    class YearInSchool(models.TextChoices):
        FRESHMAN = "FR", _("Freshman")
        SOPHOMORE = "SO", _("Sophomore")
        JUNIOR = "JR", _("Junior")
        SENIOR = "SR", _("Senior")
        GRADUATE = "GR", _("Graduate")

    year_in_school = models.CharField(
        max_length=2,
        choices=YearInSchool,
        default=YearInSchool.FRESHMAN,
    )

    def is_upperclass(self):
        return self.year_in_school in {
            self.YearInSchool.JUNIOR,
            self.YearInSchool.SENIOR,
        }
```

这些工作类似于 Python 标准库中的 [`enum`](https://docs.python.org/3/library/enum.html#module-enum)，但是做了一些修改。

- 枚举成员的值是用于构造具体数据类型的参数元组。Django 支持在此元组的末尾添加额外的字符串值，用作可读名称或 `label`。这个 `label` 可以是懒惰可翻译的字符串。因此，在大多数情况下，成员值将是一个 `(value, label)` 的 2-元组。请参阅下面的示例，了解使用更复杂的数据类型来进行选择的 [子类化选择项的示例](#field-choices-enum-subclassing)。如果未提供元组，或者最后一项不是（懒惰）字符串，则从成员名称中 [自动生成](#field-choices-enum-auto-label) `label`。
- 在值上添加 `.label` 属性，以返回人类可读的名称。
- 一些自定义属性被添加到枚举类中——`.choices`、`.labels`、`.values` 和 `.names`——以便更容易访问这些枚举的各个部分的列表。

  > **Warning**
  >
  > 这些属性名称不能作为成员名称使用，因为它们会发生冲突。
- 强制使用 [`enum.unique()`](https://docs.python.org/3/library/enum.html#enum.unique) 是为了确保不能多次定义值。在选择一个字段时，不太可能会出现这种情况。

请注意，使用 `YearInSchool.SENIOR`、`YearInSchool['SENIOR']` 或 `YearInSchool('SR')` 来访问或查找枚举成员，与成员上的 `.name` 和 `.value` 属性一样，都能正常工作。

如果你不需要将可读的名称翻译成其他语言，你可以从成员名称中推断出它们（将下划线替换为空格，并使用标题大小写）：

```pycon
>>> class Vehicle(models.TextChoices):
...     CAR = "C"
...     TRUCK = "T"
...     JET_SKI = "J"
...
>>> Vehicle.JET_SKI.label
'Jet Ski'
```

由于枚举值需要为整数的情况极为常见，Django 提供了一个 `IntegerChoices` 类。例如：

```
class Card(models.Model):
    class Suit(models.IntegerChoices):
        DIAMOND = 1
        SPADE = 2
        HEART = 3
        CLUB = 4

    suit = models.IntegerField(choices=Suit)
```

还可以利用 [Enum Functional API](https://docs.python.org/3/howto/enum.html#functional-api)，但需要注意自动生成的标签如上所示：

```pycon
>>> MedalType = models.TextChoices("MedalType", "GOLD SILVER BRONZE")
>>> MedalType.choices
[('GOLD', 'Gold'), ('SILVER', 'Silver'), ('BRONZE', 'Bronze')]
>>> Place = models.IntegerChoices("Place", "FIRST SECOND THIRD")
>>> Place.choices
[(1, 'First'), (2, 'Second'), (3, 'Third')]
```

如果你需要支持 `int` 或 `str` 以外的具体数据类型，你可以将 `Choices` 和所需的具体数据类型子类化，例如 [`date`](https://docs.python.org/3/library/datetime.html#datetime.date) 与 [`DateField`](#django.db.models.DateField) 一起使用：

```
class MoonLandings(datetime.date, models.Choices):
    APOLLO_11 = 1969, 7, 20, "Apollo 11 (Eagle)"
    APOLLO_12 = 1969, 11, 19, "Apollo 12 (Intrepid)"
    APOLLO_14 = 1971, 2, 5, "Apollo 14 (Antares)"
    APOLLO_15 = 1971, 7, 30, "Apollo 15 (Falcon)"
    APOLLO_16 = 1972, 4, 21, "Apollo 16 (Orion)"
    APOLLO_17 = 1972, 12, 11, "Apollo 17 (Challenger)"
```

还有一些注意事项需要注意：

- 枚举类型不支持 [命名组](#field-choices-named-groups)。
- 因为具有具体数据类型的枚举要求所有值都与类型相匹配，所以不能通过创建一个值为 `None` 的成员来覆盖 [空白标签](#field-choices-blank-label)。相反，在类上设置 `__empty__` 属性：

  ```
  class Answer(models.IntegerChoices):
      NO = 0, _("No")
      YES = 1, _("Yes")

      __empty__ = _("(Unknown)")
  ```

### `db_column`

#### `Field.db_column`

这个字段要使用的数据库列名。如果没有给出列名，Django 将使用字段名。

如果你的数据库列名是 SQL 的保留字，或者包含了 Python 变量名中不允许的字符——特别是连字符——那也没关系。Django 会在幕后引用列名和表名。

### `db_comment`

#### `Field.db_comment`

用于此字段的数据库列的注释。对于具有直接数据库访问权限但可能不查看您的 Django 代码的人来说，这非常有用。例如：

```
pub_date = models.DateTimeField(
    db_comment="Date and time when the article was published",
)
```

### `db_default`

#### `Field.db_default`

这个字段的默认值是数据库计算的。这可以是一个字面值或者一个数据库函数，比如： [`Now`](/zh-hans/5.2/ref/models/database-functions/#django.db.models.functions.Now):

```
created = models.DateTimeField(db_default=Now())
```

更复杂的表达式也可以使用，只要它们由字面值和数据库函数构成:

```
month_due = models.DateField(
    db_default=TruncMonth(
        Now() + timedelta(days=90),
        output_field=models.DateField(),
    )
)
```

数据库默认值不能引用其他字段或模型。例如，这是无效的:

```
end = models.IntegerField(db_default=F("start") + 50)
```

如果同时设置了 `db_default` 和 [`Field.default`](#django.db.models.Field.default)，在 Python 代码中创建实例时 `default` 会优先生效。`db_default` 仍然会在数据库级别设置，并且在使用 ORM 之外插入行或在迁移中添加新字段时仍然会使用它。

如果一个字段有 `db_default` 但没有设置 `default`，并且没有为该字段赋值，则在未保存的模型实例上会返回一个 `DatabaseDefault` 对象作为字段值。字段的实际值在保存模型实例时由数据库确定。

### `db_index`

#### `Field.db_index`

如果是 `True`，将为该字段创建数据库索引。

> **使用 indexes 选项代替。**
>
> 在可能的情况下，使用 [`Meta.indexes`](/zh-hans/5.2/ref/models/options/#django.db.models.Options.indexes) 选项。在几乎所有情况下，[`indexes`](/zh-hans/5.2/ref/models/options/#django.db.models.Options.indexes) 提供比 `db_index` 更多的功能。`db_index` 未来可能会被弃用。

### `db_tablespace`

#### `Field.db_tablespace`

如果这个字段有索引，那么要为这个字段的索引使用的 [数据库表空间](/zh-hans/5.2/topics/db/tablespaces/) 的名称。默认是项目的 [`DEFAULT_INDEX_TABLESPACE`](/zh-hans/5.2/ref/settings/#std-setting-DEFAULT_INDEX_TABLESPACE) 设置（如果有设置），或者是模型的 [`db_tablespace`](/zh-hans/5.2/ref/models/options/#django.db.models.Options.db_tablespace) （如果有）。如果后端不支持索引的表空间，则忽略此选项。

### `default`

#### `Field.default`

该字段的默认值。可以是一个值或者是个可调用的对象，如果是个可调用对象，每次实例化模型时都会调用该对象。

默认值不能是一个可更改的对象（模型实例、`list`、`set` 等），因为对该对象同一实例的引用将被用作所有新模型实例的缺省值。相反，将所需的默认值包裹在一个可调用对象中。例如，如果你想为 [`JSONField`](#django.db.models.JSONField) 指定一个默认的 `dict`，使用一个函数：

```
def contact_default():
    return {"email": "to1@example.com"}

contact_info = JSONField("ContactInfo", default=contact_default)
```

`lambda` 不能用于 `default` 等字段选项，因为它们不能被 [迁移序列化](/zh-hans/5.2/topics/migrations/#migration-serializing)。其他注意事项见该文档。

对于像 [`ForeignKey`](#django.db.models.ForeignKey) 这样映射到模型实例的字段，默认应该是它们引用的字段的值（默认是 `pk` 除非 [`to_field`](#django.db.models.ForeignKey.to_field) 被设置了），而不是模型实例。

当创建新的模型实例且没有为该字段提供值时，使用默认值。当字段是主键时，当字段设置为\`\`None\`\` 时，也使用默认值。

默认值也可以在数据库级别使用 [`Field.db_default`](#django.db.models.Field.db_default) 来设置。

### `editable`

#### `Field.editable`

If `False`, the field will not be displayed in the admin or any other
[`ModelForm`](/zh-hans/5.2/topics/forms/modelforms/#django.forms.ModelForm). It will also be skipped during [model
validation](/zh-hans/5.2/ref/models/instances/#validating-objects). Default is `True`.

### `error_messages`

#### `Field.error_messages`

`error_messages` 参数可以让你覆盖该字段引发的默认消息。传入一个与你想覆盖的错误信息相匹配的键值的字典。

错误信息键包括 `null`、`blank`、`invalid`、`invalid_choice`、`unique` 和 `unique_for_date`。在下面的 [字段类型](#field-types) 一节中为每个字段指定了额外的错误信息键。

这些错误信息通常不会传播到表单中。参见 [有关模型的 error\_messages 的注意事项](/zh-hans/5.2/topics/forms/modelforms/#considerations-regarding-model-errormessages)。

### `help_text`

#### `Field.help_text`

额外的“帮助”文本，随表单控件一同显示。即便你的字段未用于表单，它对于生成文档也是很有用的。

请注意，在自动生成的表格中，这个值 *不是* HTML 转义的。如果你愿意的话，你可以在 [`help_text`](#django.db.models.Field.help_text) 中加入 HTML。例如：

```
help_text = "Please use the following format: <em>YYYY-MM-DD</em>."
```

或者你可以使用纯文本和 [`django.utils.html.escape()`](/zh-hans/5.2/ref/utils/#django.utils.html.escape) 来转义任何 HTML 特殊字符。确保你转义任何可能来自不受信任的用户的帮助文本，以避免跨站脚本攻击。

### `primary_key`

#### `Field.primary_key`

如果设置为 `True` ，将该字段设置为该模型的主键。

If you don't specify `primary_key=True` for any field in your model and have
not defined a composite primary key, Django will automatically add a field to
hold the primary key. So, you don't need to set `primary_key=True` on any of
your fields unless you want to override the default primary-key behavior. The
type of auto-created primary key fields can be specified per app in
[`AppConfig.default_auto_field`](/zh-hans/5.2/ref/applications/#django.apps.AppConfig.default_auto_field)
or globally in the [`DEFAULT_AUTO_FIELD`](/zh-hans/5.2/ref/settings/#std-setting-DEFAULT_AUTO_FIELD) setting. For more, see
[自动设置主键](/zh-hans/5.2/topics/db/models/#automatic-primary-key-fields).

`primary_key=True` implies [`null=False`](#django.db.models.Field.null) and
[`unique=True`](#django.db.models.Field.unique). Only one field per model can set
`primary_key=True`. Composite primary keys must be defined using
[`CompositePrimaryKey`](#django.db.models.CompositePrimaryKey) instead of setting this flag to `True` for all
fields to maintain this invariant.

主键字段是只读的。如果您改变了现有对象的主键值，然后将其保存，则会在旧对象旁边创建一个新对象。

主键字段在 [`deleting`](/zh-hans/5.2/ref/models/instances/#django.db.models.Model.delete) 对象时设置为 `None`。

> **Changed in Django 5.2**
>
> The `CompositePrimaryKey` field was added.

### `unique`

#### `Field.unique`

如果设置为 `True`，这个字段必须在整个表中保持值唯一。

这是在数据库级别和模型验证中强制执行的。如果你试图保存一个在 [`unique`](#django.db.models.Field.unique) 字段中存在重复值的模型，模型的 [`save()`](/zh-hans/5.2/ref/models/instances/#django.db.models.Model.save) 方法将引发 [`django.db.IntegrityError`](/zh-hans/5.2/ref/exceptions/#django.db.IntegrityError)。

除了 [`ManyToManyField`](#django.db.models.ManyToManyField) 和 [`OneToOneField`](#django.db.models.OneToOneField) 之外，该选项对所有字段类型有效。

请注意，当 `unique` 为 `True` 时，你不需要指定 [`db_index`](#django.db.models.Field.db_index)，因为 `unique` 意味着创建一个索引。

### `unique_for_date`

#### `Field.unique_for_date`

将其设置为 [`DateField`](#django.db.models.DateField) 或 [`DateTimeField`](#django.db.models.DateTimeField) 的名称，要求该字段的日期字段值是唯一的。

例如，如果你的字段 `title` 有 `unique_for_date="pub_date"`，那么 Django 就不允许输入两条相同 `title` 和 `pub_date` 的记录。

请注意，如果将其设置为指向 [`DateTimeField`](#django.db.models.DateTimeField)，则只考虑该字段的日期部分。此外，当 [`USE_TZ`](/zh-hans/5.2/ref/settings/#std-setting-USE_TZ) 为 `True` 时，检查将在对象保存时的 [当前时区](/zh-hans/5.2/topics/i18n/timezones/#default-current-time-zone) 中进行。

这在模型验证过程中由 [`Model.validate_unique()`](/zh-hans/5.2/ref/models/instances/#django.db.models.Model.validate_unique) 强制执行，但在数据库级别上不执行。如果任何 [`unique_for_date`](#django.db.models.Field.unique_for_date) 约束涉及的字段不属于 [`ModelForm`](/zh-hans/5.2/topics/forms/modelforms/#django.forms.ModelForm) （例如，如果其中一个字段被列在\`\`exclude\`\`中，或者有 [`editable=False`](#django.db.models.Field.editable) ）， [`Model.validate_unique()`](/zh-hans/5.2/ref/models/instances/#django.db.models.Model.validate_unique) 将跳过对该特定约束的验证。

### `unique_for_month`

#### `Field.unique_for_month`

像 [`unique_for_date`](#django.db.models.Field.unique_for_date) 一样，但要求字段对月份是唯一的。

### `unique_for_year`

#### `Field.unique_for_year`

如 `unique_fordate` 和 `unique_formonth`。

### `verbose_name`

#### `Field.verbose_name`

字段的一个人类可读名称，如果没有给定详细名称，Django 会使用字段的属性名自动创建，并将下划线转换为空格。参见 [详细字段名](/zh-hans/5.2/topics/db/models/#verbose-field-names)。

### `validators`

#### `Field.validators`

要为该字段运行的验证器列表。更多信息请参见 [验证器文档](/zh-hans/5.2/ref/validators/)。

## 字段类型

### `AutoField`

#### `class AutoField(**options)`

一个 [`IntegerField`](#django.db.models.IntegerField)，根据可用的 ID 自动递增。你通常不需要直接使用它；如果你没有指定，主键字段会自动添加到你的模型中。参见 [自动设置主键](/zh-hans/5.2/topics/db/models/#automatic-primary-key-fields)。

### `BigAutoField`

#### `class BigAutoField(**options)`

一个 64 位整数，与 [`AutoField`](#django.db.models.AutoField) 很相似，但保证适合 `1` 到 `9223372036854775807` 的数字。

### `BigIntegerField`

#### `class BigIntegerField(**options)`

一个 64 位的整数，和 [`IntegerField`](#django.db.models.IntegerField) 很像，只是它保证适合从 `-9223372036854775808` 到 `9223372036854775807` 的数字。该字段的默认表单部件是一个 [`NumberInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.NumberInput)。

### `BinaryField`

#### `class BinaryField(max_length=None, **options)`

一个用于存储原始二进制数据的字段。可以指定为 [`bytes`](https://docs.python.org/3/library/stdtypes.html#bytes)、[`bytearray`](https://docs.python.org/3/library/stdtypes.html#bytearray) 或 [`memoryview`](https://docs.python.org/3/library/stdtypes.html#memoryview)。

默认情况下，`BinaryField` 将 `` ediditable` `` 设置为 `False`，在这种情况下，它不能被包含在 [`ModelForm`](/zh-hans/5.2/topics/forms/modelforms/#django.forms.ModelForm) 中。

#### `BinaryField.max_length`

可选项。字段的最大长度（以字节为单位）。Django 在验证时使用 [`MaxLengthValidator`](/zh-hans/5.2/ref/validators/#django.core.validators.MaxLengthValidator) 来强制执行最大长度。

> **滥用 BinaryField**
>
> 虽然你可能会想到在数据库中存储文件，但考虑到这在99%的情况下是糟糕的设计。这个字段 *不能* 代替正确的 [静态文件](/zh-hans/5.2/howto/static-files/) 处理。

### `BooleanField`

#### `class BooleanField(**options)`

一个 true／false 字段。

该字段的默认表单部件是 [`CheckboxInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.CheckboxInput)，或者如果 [`null=True`](#django.db.models.Field.null) 则是 [`NullBooleanSelect`](/zh-hans/5.2/ref/forms/widgets/#django.forms.NullBooleanSelect)。

当 [`Field.default`](#django.db.models.Field.default) 没有定义时，`BooleanField` 的默认值是 `None`。

### `CompositePrimaryKey`

> **New in Django 5.2**

#### `class CompositePrimaryKey(*field_names, **options)`

A virtual field used for defining a composite primary key.

This field must be defined as the model's `pk` attribute. If present, Django
will create the underlying model table with a composite primary key.

The `*field_names` argument is a list of positional field names that compose
the primary key.

See [Composite primary keys](/zh-hans/5.2/topics/composite-primary-key/) for more details.

### `CharField`

#### `class CharField(max_length=None, **options)`

一个字符串字段，适用于小到大的字符串。

对于大量的文本，使用 [`TextField`](#django.db.models.TextField)。

该字段的默认表单部件是一个 [`TextInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.TextInput)。

[`CharField`](#django.db.models.CharField) 具有以下额外参数：

#### `CharField.max_length`

The maximum length (in characters) of the field. The `max_length`
is enforced at the database level and in Django's validation using
[`MaxLengthValidator`](/zh-hans/5.2/ref/validators/#django.core.validators.MaxLengthValidator). It's required for all
database backends included with Django except PostgreSQL and SQLite, which
supports unlimited `VARCHAR` columns.

> **Note**
>
> 如果你编写的应用程序必须可移植到多个数据库后端，你应该意识到，有些后端对 `max_length` 有限制。详情请参考 [数据库后端注释](/zh-hans/5.2/ref/databases/)。

> **Changed in Django 5.2**
>
> Support for unlimited `VARCHAR` columns was added on SQLite.

#### `CharField.db_collation`

可选的。该字段的数据库字符序名称。

> **Note**
>
> 字符序名称是不标准化的。因此，这将无法在多个数据库后端之间进行移植。

> **Oracle**
>
> Oracle 只有在 `MAX_STRING_SIZE` 数据库初始化参数被设置为 `EXTENDED` 时，才支持字符序。

### `DateField`

#### `class DateField(auto_now=False, auto_now_add=False, **options)`

一个日期，在 Python 中用一个 `datetime.date` 实例表示。有一些额外的、可选的参数。

#### `DateField.auto_now`

每次保存对象时，自动将该字段设置为现在。对于“最后修改”的时间戳很有用。请注意，当前日期 *总是* 被使用，而不仅仅是一个你可以覆盖的默认值。

只有在调用 [`Model.save()`](/zh-hans/5.2/ref/models/instances/#django.db.models.Model.save) 时，该字段才会自动更新。当以其他方式对其他字段进行更新时，如 [`QuerySet.update()`](/zh-hans/5.2/ref/models/querysets/#django.db.models.query.QuerySet.update)，该字段不会被更新，尽管你可以在这样的更新中为该字段指定一个自定义值。

#### `DateField.auto_now_add`

当第一次创建对象时，自动将该字段设置为现在。对创建时间戳很有用。请注意，当前日期是 *始终* 使用的；它不是一个你可以覆盖的默认值。因此，即使你在创建对象时为该字段设置了一个值，它也会被忽略。如果你想修改这个字段，可以设置以下内容来代替 `auto_now_add=True` ：

- 对于 [`DateField`](#django.db.models.DateField): `default=date.today` ——来自 [`datetime.date.today()`](https://docs.python.org/3/library/datetime.html#datetime.date.today)
- 对于 [`DateTimeField`](#django.db.models.DateTimeField): `default=timezone.now` ——来自 [`django.utils.timezone.now()`](/zh-hans/5.2/ref/utils/#django.utils.timezone.now)

该字段的默认表单部件是一个 [`DateInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.DateInput)。管理中增加了一个 JavaScript 日历，以及“今天”的快捷方式。包含一个额外的 `invalid_date` 错误信息键。

`auto_now_add`、`auto_now` 和 `default` 选项是相互排斥的。这些选项的任何组合都会导致错误。

> **Note**
>
> 目前，将 `auto_now` 或 `auto_now_add` 设置为 `True`，将导致该字段设置为 `editable=False` 和 `blank=True`。

> **Note**
>
> `auto_now` 和 `auto_now_add` 选项将始终使用创建或更新时 [默认时区](/zh-hans/5.2/topics/i18n/timezones/#default-current-time-zone) 的日期。如果你需要一些不同的东西，你可能需要考虑使用你自己的可调用的默认值，或者覆盖 `save()` 而不是使用 `auto_now` 或 `auto_now_add` ；或者使用 `DateTimeField` 而不是 `DateField`，并决定如何在显示时间处理从日期时间到日期的转换。

> **Warning**
>
> 始终使用带有 `datetime.date` 实例的 [`DateField`](#django.db.models.DateField)。
>
> 如果你有一个 `datetime.datetime` 实例，建议先将其转换为 `datetime.date`。如果不这样做，[`DateField`](#django.db.models.DateField) 会将 `datetime.datetime` 本地化为 [默认时区](/zh-hans/5.2/topics/i18n/timezones/#default-current-time-zone) 并将其转换为 `datetime.date` 实例，移除其时间部分。这在存储和比较时都是如此。

> **Warning**
>
> On PostgreSQL and MySQL, arithmetic operations on a `DateField` with a
> [`timedelta`](https://docs.python.org/3/library/datetime.html#datetime.timedelta) return a `datetime` instead of a `date`.
> This occurs because Python's `timedelta` is converted to SQL
> `INTERVAL`, and the SQL operation `date +/- interval` returns a
> `timestamp` on these databases.
>
> To ensure a `date` result, use one of the following approaches. Either
> explicitly cast the result to a date:
>
> ```
> import datetime
> from django.db.models import DateField, F
> from django.db.models.functions import Cast
>
> qs = MyModel.objects.annotate(
>     previous_day=Cast(
>         F("date_field") - datetime.timedelta(days=1),
>         output_field=DateField(),
>     )
> )
> ```
>
> Or on PostgreSQL only, use integer arithmetic to represent days:
>
> ```
> from django.db.models import DateField, ExpressionWrapper, F
>
> qs = MyModel.objects.annotate(
>     previous_day=ExpressionWrapper(
>         F("date_field") - 1,  # Subtract 1 day as integer
>         output_field=DateField(),
>     )
> )
> ```

### `DateTimeField`

#### `class DateTimeField(auto_now=False, auto_now_add=False, **options)`

一个日期和时间，在 Python 中用一个 `datetime.datetime` 实例表示。与 [`DateField`](#django.db.models.DateField) 一样，使用相同的额外参数。

该字段的默认表单部件是一个单独的 [`DateTimeInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.DateTimeInput)。管理中使用两个单独的 [`TextInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.TextInput) 部件，并使用 JavaScript 快捷方式。

> **Warning**
>
> 始终使用带有 `datetime.datetime` 实例的 [`DateTimeField`](#django.db.models.DateTimeField)。
>
> 如果你有一个 `datetime.date` 实例，建议先将其转换为 `datetime.datetime`。如果不这样做，[`DateTimeField`](#django.db.models.DateTimeField) 将使用 [默认时区](/zh-hans/5.2/topics/i18n/timezones/#default-current-time-zone) 中的午夜作为时间部分。这在存储和比较时都是如此。要将 [`DateTimeField`](#django.db.models.DateTimeField) 的日期部分与 `datetime.date` 实例进行比较，请使用 [`date`](/zh-hans/5.2/ref/models/querysets/#std-fieldlookup-date) 查找。

### `DecimalField`

#### `class DecimalField(max_digits=None, decimal_places=None, **options)`

一个固定精度的十进制数，在 Python 中用一个 [`Decimal`](https://docs.python.org/3/library/decimal.html#decimal.Decimal) 实例来表示。它使用 [`DecimalValidator`](/zh-hans/5.2/ref/validators/#django.core.validators.DecimalValidator) 验证输入。

有以下 **必需** 参数：

#### `DecimalField.max_digits`

数字中允许的最大位数。请注意，这个数字必须大于或等于 `decimal_places`。

#### `DecimalField.decimal_places`

与数字一起存储的小数位数。

例如，要存储最高为 `999.99` 的数字，精度为小数点后 2 位，你可以使用：

```
models.DecimalField(..., max_digits=5, decimal_places=2)
```

并以 10 位小数的精度来存储最多约 10 亿的数字：

```
models.DecimalField(..., max_digits=19, decimal_places=10)
```

当 [`localize`](/zh-hans/5.2/ref/forms/fields/#django.forms.Field.localize) 为 `False` 时是 [`NumberInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.NumberInput) 否则，该字段的默认表单部件是 [`TextInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.TextInput)。

> **Note**
>
> 关于 [`FloatField`](#django.db.models.FloatField) 和 [`DecimalField`](#django.db.models.DecimalField) 类之间差异的更多信息，请参见 [FloatField vs. DecimalField](#floatfield-vs-decimalfield)。你还应该注意小数字段的 [SQLite 限制](/zh-hans/5.2/ref/databases/#sqlite-decimal-handling)。

### `DurationField`

#### `class DurationField(**options)`

一个用于存储时间段的字段——在 Python 中用 [`timedelta`](https://docs.python.org/3/library/datetime.html#datetime.timedelta) 建模。当在 PostgreSQL 上使用时，使用的数据类型是 `interval`，在 Oracle 上使用的数据类型是 `INTERVAL DAY(9) TO SECOND(6)`。否则使用微秒的 `bigint`。

> **Note**
>
> `DurationField` 的算术在大多数情况下是可行的。但在 PostgreSQL 以外的所有数据库中，将 `DurationField` 的值与 `DateTimeField` 实例上的算术进行比较，将无法达到预期的效果。

### `EmailField`

#### `class EmailField(max_length=254, **options)`

一个 [`CharField`](#django.db.models.CharField)，使用 [`EmailValidator`](/zh-hans/5.2/ref/validators/#django.core.validators.EmailValidator) 来检查该值是否为有效的电子邮件地址。

### `FileField`

#### `class FileField(upload_to='', storage=None, max_length=100, **options)`

一个文件上传字段

> **Note**
>
> `primary_key` 参数不支持，如果使用，会引起错误。

具有以下可选参数：

#### `FileField.upload_to`

这个属性提供了一种设置上传目录和文件名的方式，可以有两种设置方式。在这两种情况下，值都会传递给 [`Storage.save()`](/zh-hans/5.2/ref/files/storage/#django.core.files.storage.Storage.save) 方法。

如果你指定一个字符串值或一个 [`Path`](https://docs.python.org/3/library/pathlib.html#pathlib.Path)，它可能包含 [`strftime()`](https://docs.python.org/3/library/time.html#time.strftime) 格式，它将被文件上传的日期／时间所代替（这样上传的文件就不会填满指定的目录）。例如：

```
class MyModel(models.Model):
    # file will be uploaded to MEDIA_ROOT/uploads
    upload = models.FileField(upload_to="uploads/")
    # or...
    # file will be saved to MEDIA_ROOT/uploads/2015/01/30
    upload = models.FileField(upload_to="uploads/%Y/%m/%d/")
```

如果你使用的是默认的 [`FileSystemStorage`](/zh-hans/5.2/ref/files/storage/#django.core.files.storage.FileSystemStorage)，这个字符串的值将被附加到你的 [`MEDIA_ROOT`](/zh-hans/5.2/ref/settings/#std-setting-MEDIA_ROOT) 路径后面，形成本地文件系统中上传文件的存储位置。如果你使用的是不同的存储系统，请检查该存储系统的文档，看看它是如何处理 `upload_to` 的。

`upload_to` 也可以是一个可调用对象，如函数。这个函数将被调用以获得上传路径，包括文件名。这个可调用对象必须接受两个参数，并返回一个 Unix 风格的路径（带斜线），以便传给存储系统。这两个参数是：

| 参数 | 描述 |
| --- | --- |
| `instance` | 定义 `FileField` 的模型实例。更具体地说，这是附加当前文件的特定实例。<br><br>在大多数情况下，这个对象还没有被保存到数据库，所以如果它使用默认的 `AutoField`，*它的主键字段可能还没有一个值*。 |
| `filename` | 最初给文件的文件名。在确定最终目标路径时，可能会考虑到，也可能不会考虑到。 |

例子：

```
def user_directory_path(instance, filename):
    # file will be uploaded to MEDIA_ROOT/user_<id>/<filename>
    return "user_{0}/{1}".format(instance.user.id, filename)

class MyModel(models.Model):
    upload = models.FileField(upload_to=user_directory_path)
```

#### `FileField.storage`

一个存储对象，或是一个返回存储对象的可调用对象。它处理你的文件的存储和检索。参见 [管理文件](/zh-hans/5.2/topics/files/)，了解如何提供这个对象。

该字段的默认表单部件是一个 [`ClearableFileInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.ClearableFileInput)。

在模型中使用 [`FileField`](#django.db.models.FileField) 或 [`ImageField`](#django.db.models.ImageField) （见下文）需要几个步骤：

1. 在你的配置文件中，你需要将 [`MEDIA_ROOT`](/zh-hans/5.2/ref/settings/#std-setting-MEDIA_ROOT) 定义为你希望 Django 存储上传文件的目录的完整路径。（为了提高性能，这些文件不会存储在数据库中。）将 [`MEDIA_URL`](/zh-hans/5.2/ref/settings/#std-setting-MEDIA_URL) 定义为该目录的基本公共 URL。确保这个目录是可以被网络服务器的用户账户写入的。
2. 将 [`FileField`](#django.db.models.FileField) 或 [`ImageField`](#django.db.models.ImageField) 添加到你的模型中，定义 [`upload_to`](#django.db.models.FileField.upload_to) 选项，指定 [`MEDIA_ROOT`](/zh-hans/5.2/ref/settings/#std-setting-MEDIA_ROOT) 的子目录，用于上传文件。
3. 所有这些将被存储在你的数据库中的是一个文件的路径（相对于 [`MEDIA_ROOT`](/zh-hans/5.2/ref/settings/#std-setting-MEDIA_ROOT) ）。你很可能要使用 Django 提供的方便的 [`url`](#django.db.models.fields.files.FieldFile.url) 属性。例如，如果你的 [`ImageField`](#django.db.models.ImageField) 叫做 `mug_shot`，你可以在模板中使用 `{{ object.mug_shot.url }}` 获取图片的绝对路径。

例如，你的 [`MEDIA_ROOT`](/zh-hans/5.2/ref/settings/#std-setting-MEDIA_ROOT) 设置为 `'/home/media'`， [`upload_to`](#django.db.models.FileField.upload_to) 设置为 `'photos/%Y/%m/%d'`。[`upload_to`](#django.db.models.FileField.upload_to) 中的 `'%Y/%m/%d'` 部分是 [`strftime()`](https://docs.python.org/3/library/time.html#time.strftime) 格式化，`'%Y'` 是四位数的年，`'%m'` 是两位数的月，`'%d'` 是两位数的日。如果你在 2007 年 1 月 15 日上传了一个文件，它将被保存在 `/home/media/photos/2007/01/15` 目录下。

如果你想检索上传文件的盘上文件名，或者文件的大小，可以分别使用 [`name`](/zh-hans/5.2/ref/files/file/#django.core.files.File.name) 和 [`size`](/zh-hans/5.2/ref/files/file/#django.core.files.File.size) 属性；关于可用属性和方法的更多信息，请参见 [`File`](/zh-hans/5.2/ref/files/file/#django.core.files.File) 类参考和 [管理文件](/zh-hans/5.2/topics/files/) 主题指南。

> **Note**
>
> 文件在数据库中作为保存模型的一部分，因此在模型被保存之前，不能依赖磁盘上使用的实际文件名。

上传的文件的相对 URL 可以通过 `url` 属性获得。内部调用底层 [`Storage`](/zh-hans/5.2/ref/files/storage/#django.core.files.storage.Storage) 类的 `store()` 方法。

请注意，无论何时你处理上传的文件，你都应该密切注意你在哪里上传文件以及它们是什么类型的文件，以避免安全漏洞。 *验证所有上传的文件* ，这样你就能确定文件是你认为的那样。例如，如果你盲目地让别人上传文件，而不进行验证，到你的网站服务器的文件根目录中，那么有人就可以上传 CGI 或 PHP 脚本，并通过访问你网站上的 URL 来执行该脚本。不要允许这样做。

另外要注意的是，即使是上传的 HTML 文件，由于可以被浏览器执行（虽然不能被服务器执行），也会造成相当于 XSS 或 CSRF 攻击的安全威胁。

[`FileField`](#django.db.models.FileField) 实例在数据库中被创建为 `varchar` 列，默认最大长度为 100 个字符。与其他字段一样，你可以使用 [`max_length`](#django.db.models.CharField.max_length) 参数改变最大长度。

#### `FileField` 和 `FieldFile`

#### `class FieldFile`

当你访问一个模型上的 [`FileField`](#django.db.models.FileField) 时，你会得到一个 [`FieldFile`](#django.db.models.fields.files.FieldFile) 的实例作为访问底层文件的代理。

[`FieldFile`](#django.db.models.fields.files.FieldFile) 的 API 与 [`File`](/zh-hans/5.2/ref/files/file/#django.core.files.File) 的 API 相同，但有一个关键的区别。*该类所封装的对象不一定是 Python 内置文件对象的封装* 相反，它是 `Storage.open()` 方法结果的封装，该方法可能是 [`File`](/zh-hans/5.2/ref/files/file/#django.core.files.File) 对象，也可能是自定义存储对 [`File`](/zh-hans/5.2/ref/files/file/#django.core.files.File) API 的实现。

除了从 [`File`](/zh-hans/5.2/ref/files/file/#django.core.files.File) 继承的 API，如 `read()` 和 `write()` 之外，[`FieldFile`](#django.db.models.fields.files.FieldFile) 还包括一些可以用来与底层文件交互的方法：

> **Warning**
>
> 该类的两个方法 [`save()`](#django.db.models.fields.files.FieldFile.save) 和 [`delete()`](#django.db.models.fields.files.FieldFile.delete)，默认为将与相关 `FieldFile` 的模型对象保存在数据库中。

#### `FieldFile.name`

文件名，包括从关联的 [`Storage`](/zh-hans/5.2/ref/files/storage/#django.core.files.storage.Storage) 的根部开始的相对路径 [`FileField`](#django.db.models.FileField)。

#### `FieldFile.path`

一个只读属性，通过调用底层的 [`path()`](/zh-hans/5.2/ref/files/storage/#django.core.files.storage.Storage.path) 方法，访问文件的本地文件系统路径。

#### `FieldFile.size`

底层 [`Storage.size()`](/zh-hans/5.2/ref/files/storage/#django.core.files.storage.Storage.size) 方法的结果。

#### `FieldFile.url`

一个只读属性，通过调用底层 [`Storage`](/zh-hans/5.2/ref/files/storage/#django.core.files.storage.Storage) 类的 [`Storage()`](/zh-hans/5.2/ref/files/storage/#django.core.files.storage.Storage) 方法来访问文件的相对 URL。

#### `FieldFile.open(mode='rb')`

以指定的 `mode` 打开或重新打开与该实例相关的文件。与标准的 Python `open()` 方法不同，它不返回一个文件描述符。

因为在访问底层文件时，底层文件是隐式打开的，所以除了重置底层文件的指针或改变 `mode` 之外，可能没有必要调用这个方法。

#### `FieldFile.close()`

类似于标准的 Python `file.close()` 方法，关闭与该实例相关的文件。

#### `FieldFile.save(name, content, save=True)`

这个方法接收一个文件名和文件内容，并将它们传递给字段的存储类，然后将存储的文件与模型字段关联。如果你想手动将文件数据与模型上的 [`FileField`](#django.db.models.FileField) 实例关联起来，那么 `save()` 方法用来持久化该文件数据。

取两个必要的参数。`name` 是文件的名称，`content` 是包含文件内容的对象。 可选的 `save` 参数控制在与该字段相关联的文件被更改后是否保存模型实例。默认为 `True`。

注意 `content` 参数应该是 [`django.core.files.File`](/zh-hans/5.2/ref/files/file/#django.core.files.File) 的实例，而不是 Python 内置的文件对象。你可以从现有的 Python 文件对象构造一个 [`File`](/zh-hans/5.2/ref/files/file/#django.core.files.File)，像这样：

```
from django.core.files import File

# Open an existing file using Python's built-in open()
f = open("/path/to/hello.world")
myfile = File(f)
```

或者你可以从 Python 字符串中构建一个像这样的字符串：

```
from django.core.files.base import ContentFile

myfile = ContentFile("hello world")
```

更多信息，请参见 [管理文件](/zh-hans/5.2/topics/files/)。

#### `FieldFile.delete(save=True)`

删除与此实例相关的文件，并清除字段的所有属性。注意：如果在调用 `delete()` 时，文件恰好被打开，本方法将关闭该文件。

可选的 `save` 参数控制在删除与该字段相关的文件后是否保存模型实例。默认值为 `True`。

请注意，当一个模型被删除时，相关文件不会被删除。如果你需要清理遗留文件，你需要自己处理（例如，使用自定义管理命令，可以手动运行或通过例如 cron 定期运行）。

### `FilePathField`

#### `class FilePathField(path='', match=None, recursive=False, allow_files=True, allow_folders=False, max_length=100, **options)`

一个 [`CharField`](#django.db.models.CharField)，其选择仅限于文件系统中某个目录下的文件名。有一些特殊的参数，其中第一个参数是 **必须的**。

#### `FilePathField.path`

必须的。一个目录的绝对文件系统路径，这个 [`FilePathField`](#django.db.models.FilePathField) 应从该目录中获取其选择。例如：`"/home/images"`。

`path` 也可以是一个可调用对象，可以是在运行时动态设置路径的函数。例如：

```
import os
from django.conf import settings
from django.db import models

def images_path():
    return os.path.join(settings.LOCAL_FILE_DIR, "images")

class MyModel(models.Model):
    file = models.FilePathField(path=images_path)
```

#### `FilePathField.match`

可选。一个正则表达式，作为一个字符串， [`FilePathField`](#django.db.models.FilePathField) 将用于过滤文件名。请注意，正则表达式将被应用于基本文件名，而不是完整的路径。例如：`"foo.*.txt$"`，它将匹配名为 `foo23.txt` 的文件，但不匹配 `bar.txt` 或 `foo23.png`。

#### `FilePathField.recursive`

可选。`True` 或 `False`。默认为 `False`。指定是否包含 [`path`](#django.db.models.FilePathField.path) 的所有子目录。

#### `FilePathField.allow_files`

可选。 `True` 或 `False`。 默认值是 `True`。 指定是否应该包含指定位置的文件。 这个或 [`allow_folders`](#django.db.models.FilePathField.allow_folders) 必须是 `True`。

#### `FilePathField.allow_folders`

可选。 `True` 或 `False`。 默认为 `False`。 指定是否应该包含指定位置的文件夹。 这个或 [`allow_files`](#django.db.models.FilePathField.allow_files) 必须是 `True`。

一个潜在的问题是 [`match`](#django.db.models.FilePathField.match) 适用于基本文件名，而不是完整的路径。所以，这个例子：

```
FilePathField(path="/home/images", match="foo.*", recursive=True)
```

...将匹配 `/home/images/foo.png`，但不匹配 `/home/images/foo/bar.png`，因为 [`match`](#django.db.models.FilePathField.match) 适用于基本文件名（ `foo.png` 和 `bar.png` ）。

[`FilePathField`](#django.db.models.FilePathField) 实例在数据库中作为 `varchar` 列创建，默认最大长度为 100 个字符。与其他字段一样，你可以使用 [`max_length`](#django.db.models.CharField.max_length) 参数改变最大长度。

### `FloatField`

#### `class FloatField(**options)`

在 Python 中用一个 `float` 实例表示的浮点数。

当 [`localize`](/zh-hans/5.2/ref/forms/fields/#django.forms.Field.localize) 为 `False` 时是 [`NumberInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.NumberInput) 否则，该字段的默认表单部件是 [`TextInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.TextInput)。

> **FloatField vs. DecimalField**
>
> [`FloatField`](#django.db.models.FloatField) 类有时会与 [`DecimalField`](#django.db.models.DecimalField) 类混淆。虽然它们都表示实数，但它们表示的方式不同。`FloatField` 内部使用 Python 的 `float` 类型，而 `DecimalField` 则使用 Python 的 `Decimal` 类型。关于两者之间的区别，请参见 Python 的 [`decimal`](https://docs.python.org/3/library/decimal.html#module-decimal) 模块的文档。

### `GeneratedField`

#### `class GeneratedField(expression, output_field, db_persist=None, **kwargs)`

这是一个根据模型中的其他字段始终计算的字段。该字段由数据库自身进行管理和更新。使用 `GENERATED ALWAYS` SQL 语法。

有两种类型的生成列：存储的和虚拟的。存储的生成列在写入（插入或更新）时进行计算，并占用存储空间，就像是普通列一样。虚拟生成列不占用存储空间，在读取时进行计算。因此，虚拟生成列类似于视图，而存储的生成列类似于物化视图。

#### `GeneratedField.expression`

数据库使用的 [`Expression`](/zh-hans/5.2/ref/models/expressions/#django.db.models.Expression) 在每次模型更改时自动设置字段值。

这些表达式应该是确定性的，并且只引用模型内部（同一数据库表）的字段。生成的字段不能引用其他生成的字段。数据库后端可以强加更多的限制。

#### `GeneratedField.output_field`

一个模型字段实例，用于定义字段的数据类型。

#### `GeneratedField.db_persist`

确定数据库列是否应该占用存储空间，就像是一个真实的列一样。如果为 `False`，则该列将作为虚拟列，不会占用数据库存储空间。

PostgreSQL 仅支持持久列。Oracle 仅支持虚拟列。

> **刷新数据**
>
> Since the database computes the value, the object must be reloaded to
> access the new value after [`save()`](/zh-hans/5.2/ref/models/instances/#django.db.models.Model.save), for example, by using
> [`refresh_from_db()`](/zh-hans/5.2/ref/models/instances/#django.db.models.Model.refresh_from_db).

> **数据库限制**
>
> Django 并不验证生成字段上的许多特定于数据库的限制，数据库可能会引发错误，例如，PostgreSQL 要求在生成列中引用的函数和操作符必须标记为 `IMMUTABLE`。
>
> 你应该始终检查你的数据库是否支持 `expression`。请查看 [MariaDB](https://mariadb.com/kb/en/generated-columns/#expression-support)、[MySQL](https://dev.mysql.com/doc/refman/en/create-table-generated-columns.html)、[Oracle](https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/CREATE-TABLE.html#GUID-F9CE0CC3-13AE-4744-A43C-EAC7A71AAAB6__BABIIGBD)、[PostgreSQL](https://www.postgresql.org/docs/current/ddl-generated-columns.html) 或 [SQLite](https://www.sqlite.org/gencol.html#limitations) 文档。

### `GenericIPAddressField`

#### `class GenericIPAddressField(protocol='both', unpack_ipv4=False, **options)`

IPv4 或 IPv6 地址，字符串格式（如 `192.0.2.30` 或 `2a02:42fe::4` ）。该字段的默认表单部件是一个 [`TextInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.TextInput)。

IPv6 地址规范化遵循 [**RFC 4291 Section 2.2**](https://datatracker.ietf.org/doc/html/rfc4291.html#section-2.2) 第 2.2 节，包括使用该节第 3 段建议的 IPv4 格式，如 `::fffff:192.0.2.0`。例如，`2001:0::0:01` 将被标准化为 `2001::1`，`::fffff:0a0a:0a0a` 将被标准化为 `::fffff:10.10.10.10`。所有字符都转换为小写。

#### `GenericIPAddressField.protocol`

将有效输入限制为指定协议。接受的值是 `'both'` （默认）、`'IPv4'` 或 `'IPv6'`。匹配是不分大小写的。

#### `GenericIPAddressField.unpack_ipv4`

解压 IPv4 映射地址，如 `::fffff:192.0.2.1`。如果启用该选项，该地址将被解压为 `192.0.2.1`。默认为禁用。只有当 `protocol` 设置为 `'both'` 时才会启用。

如果允许空值，就必须允许 null 值，因为空值会被存储为 null。

### `ImageField`

#### `class ImageField(upload_to=None, height_field=None, width_field=None, max_length=100, **options)`

继承 [`FileField`](#django.db.models.FileField) 的所有属性和方法，但也验证上传的对象是有效的图像。

除了 [`FileField`](#django.db.models.FileField) 的特殊属性外， [`ImageField`](#django.db.models.ImageField) 也有 `height` 和 `width` 属性。

为了方便对这些属性进行查询，[`ImageField`](#django.db.models.ImageField) 具有以下可选参数：

#### `ImageField.height_field`

每次设置图像对象时自动填充图像高度的模型字段名称。

#### `ImageField.width_field`

每次设置图像对象时自动填充图像宽度的模型字段名称。

需要 [pillow](https://pypi.org/project/pillow/) 库。

[`ImageField`](#django.db.models.ImageField) 实例在数据库中创建为 `varchar` 列，默认最大长度为 100 个字符。与其他字段一样，你可以使用 [`max_length`](#django.db.models.CharField.max_length) 参数改变最大长度。

该字段的默认表单部件是一个 [`ClearableFileInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.ClearableFileInput)。

### `IntegerField`

#### `class IntegerField(**options)`

An integer. Values are only allowed between certain (database-dependent)
points. Values from `-2147483648` to `2147483647` are compatible in all
databases supported by Django.

它使用 [`MinValueValidator`](/zh-hans/5.2/ref/validators/#django.core.validators.MinValueValidator) 和 [`MaxValueValidator`](/zh-hans/5.2/ref/validators/#django.core.validators.MaxValueValidator) 根据默认数据库支持的值来验证输入。

当 [`localize`](/zh-hans/5.2/ref/forms/fields/#django.forms.Field.localize) 为 `False` 时是 [`NumberInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.NumberInput) 否则，该字段的默认表单部件是 [`TextInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.TextInput)。

### `JSONField`

#### `class JSONField(encoder=None, decoder=None, **options)`

一个用于存储 JSON 编码数据的字段。在 Python 中，数据以其 Python 本地格式表示：字典、列表、字符串、数字、布尔值和 `None`。

`JSONField` 在 MariaDB、MySQL、Oracle、PostgreSQL 和 SQLite（启用了 [JSON1 扩展](/zh-hans/5.2/ref/databases/#sqlite-json1)）上都得到了支持。

#### `JSONField.encoder`

一个可选的 [`json.JSONEncoder`](https://docs.python.org/3/library/json.html#json.JSONEncoder) 子类，用于序列化标准 JSON 序列化器不支持的数据类型（例如 `datetime.datetime` 或 [`UUID`](https://docs.python.org/3/library/uuid.html#uuid.UUID) ）。例如，你可以使用 [`DjangoJSONEncoder`](/zh-hans/5.2/topics/serialization/#django.core.serializers.json.DjangoJSONEncoder) 类。

默认为 `json.JSONEncoder`。

#### `JSONField.decoder`

一个可选的 [`json.JSONDecoder`](https://docs.python.org/3/library/json.html#json.JSONDecoder) 子类，用于反序列化从数据库中获取的值。该值将采用自定义编码器选择的格式（通常是字符串）。你的反序列化可能需要考虑到你无法确定输入类型的事实。例如，你有可能返回一个 `datetime`，实际上是一个字符串，而这个字符串恰好与 `datetime` 选择的格式相同。

默认为 `json.JSONDecoder`。

要在数据库中查询 `JSONField`，请看 [查询 JSONField](/zh-hans/5.2/topics/db/queries/#querying-jsonfield)。

> **默认值**
>
> 如果你给字段一个 [`default`](#django.db.models.Field.default)，确保它是一个可调用对象，例如 [`dict`](https://docs.python.org/3/library/stdtypes.html#dict) 类或一个每次返回新对象的函数。不正确地使用可变对象，比如 `default={}` 或 `default=[]`，会创建一个在所有实例之间共享的可变默认值。

> **索引**
>
> [`Index`](/zh-hans/5.2/ref/models/indexes/#django.db.models.Index) 和 [`Field.db_index`](#django.db.models.Field.db_index) 都创建了一个 B 树索引，在查询 `JSONField` 的时候并不是特别有用。仅在 PostgreSQL 上，可以使用 [`GinIndex`](/zh-hans/5.2/ref/contrib/postgres/indexes/#django.contrib.postgres.indexes.GinIndex) 比较适合。

> **PostgreSQL 用户**
>
> PostgreSQL 有两种基于 JSON 的原生数据类型： `json` 和 `jsonb`。它们之间的主要区别在于它们的存储方式和查询方式。PostgreSQL 的 `json` 字段是作为 JSON 的原始字符串表示来存储的，当根据键来查询时，必须同时进行解码。`jsonb` 字段是基于 JSON 的实际结构存储的，它允许索引。这样做的代价是在写入 `jsonb` 字段时增加了一点成本。`JSONField` 使用 `jsonb`。

> **Oracle 用户**
>
> Oracle 数据库不支持存储 JSON 标量值。只支持 JSON 对象和数组（在 Python 中使用 [`dict`](https://docs.python.org/3/library/stdtypes.html#dict) 和 [`list`](https://docs.python.org/3/library/stdtypes.html#list) 表示)。

### `PositiveBigIntegerField`

#### `class PositiveBigIntegerField(**options)`

Like a [`PositiveIntegerField`](#django.db.models.PositiveIntegerField), but only allows values under a certain
(database-dependent) point. Values from `0` to `9223372036854775807` are
compatible in all databases supported by Django.

### `PositiveIntegerField`

#### `class PositiveIntegerField(**options)`

Like an [`IntegerField`](#django.db.models.IntegerField), but must be either positive or zero (`0`).
Values are only allowed under a certain (database-dependent) point. Values from
`0` to `2147483647` are compatible in all databases supported by Django.
The value `0` is accepted for backward compatibility reasons.

### `PositiveSmallIntegerField`

#### `class PositiveSmallIntegerField(**options)`

Like a [`PositiveIntegerField`](#django.db.models.PositiveIntegerField), but only allows values under a certain
(database-dependent) point. Values from `0` to `32767` are compatible in
all databases supported by Django.

### `SlugField`

#### `class SlugField(max_length=50, **options)`

[Slug](/zh-hans/5.2/glossary/#term-slug) 是一个报纸术语。slug 是一个简短的标签，只包含字母、数字、下划线或连字符。它们一般用于 URL 中。

像 CharField 一样，你可以指定 [`max_length`](#django.db.models.CharField.max_length) （也请阅读那一节中关于数据库可移植性和 [`max_length`](#django.db.models.CharField.max_length) 的说明）。如果没有指定 [`max_length`](#django.db.models.CharField.max_length)，Django 将使用默认长度 50。

意味着将 [`Field.db_index`](#django.db.models.Field.db_index) 设置为 `True`。

基于其他值的值自动预填充一个 SlugField 通常是很有用的。 你可以在管理中使用 [`prepopulated_fields`](/zh-hans/5.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.prepopulated_fields) 来自动完成。

它使用 [`validate_slug`](/zh-hans/5.2/ref/validators/#django.core.validators.validate_slug) 或 [`validate_unicode_slug`](/zh-hans/5.2/ref/validators/#django.core.validators.validate_unicode_slug) 进行验证。

#### `SlugField.allow_unicode`

如果是 `True`，该字段除了接受 ASCII 字母外，还接受 Unicode 字母。默认值为 `False`。

### `SmallAutoField`

#### `class SmallAutoField(**options)`

Like an [`AutoField`](#django.db.models.AutoField), but only allows values under a certain
(database-dependent) limit. Values from `1` to `32767` are compatible in
all databases supported by Django.

### `SmallIntegerField`

#### `class SmallIntegerField(**options)`

Like an [`IntegerField`](#django.db.models.IntegerField), but only allows values under a certain
(database-dependent) point. Values from `-32768` to `32767` are compatible
in all databases supported by Django.

### `TextField`

#### `class TextField(**options)`

一个大的文本字段。该字段的默认表单部件是一个 [`Textarea`](/zh-hans/5.2/ref/forms/widgets/#django.forms.Textarea)。

如果你指定了 `max_length` 属性，它将反映在自动生成的表单字段的 [`Textarea`](/zh-hans/5.2/ref/forms/widgets/#django.forms.Textarea) 部件中。但是，它并没有在模型或数据库层面被强制执行。使用一个 [`CharField`](#django.db.models.CharField) 来实现。

#### `TextField.db_collation`

可选的。该字段的数据库字符序名称。

> **Note**
>
> 字符序名称是不标准化的。因此，这将无法在多个数据库后端之间进行移植。

> **Oracle**
>
> Oracle 不支持 `TextField` 的字符序。

### `TimeField`

#### `class TimeField(auto_now=False, auto_now_add=False, **options)`

一个时间，在 Python 中用 `datetime.time` 实例表示。接受与 [`DateField`](#django.db.models.DateField) 相同的自动填充选项。

该字段默认的表单部件t是一个 [`TimeInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.TimeInput)。管理中添加了一些 JavaScript 快捷方式。

### `URLField`

#### `class URLField(max_length=200, **options)`

URL 的 [`CharField`](#django.db.models.CharField)，由 [`URLValidator`](/zh-hans/5.2/ref/validators/#django.core.validators.URLValidator) 验证。

该字段的默认表单部件是一个 [`URLInput`](/zh-hans/5.2/ref/forms/widgets/#django.forms.URLInput)。

像所有的 [`CharField`](#django.db.models.CharField) 子类一样， [`URLField`](#django.db.models.URLField) 接受可选的 [`max_length`](#django.db.models.CharField.max_length) 参数。如果你没有指定 [`max_length`](#django.db.models.CharField.max_length) 参数，则使用默认的 200。

### `UUIDField`

#### `class UUIDField(**options)`

用于存储通用唯一标识符的字段。使用 Python 的 [`UUID`](https://docs.python.org/3/library/uuid.html#uuid.UUID) 类。在 PostgreSQL 和 MariaDB 10.7+ 上使用时，将存储在 `uuid` 数据类型中，否则存储在 `char(32)` 中。

通用唯一标识符是 [`primary_key`](#django.db.models.Field.primary_key) 的 [`AutoField`](#django.db.models.AutoField) 的一个很好的替代方案。数据库不会为你生成 UUID，所以建议使用 [`default`](#django.db.models.Field.default) ：

```
import uuid
from django.db import models

class MyUUIDModel(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    # other fields
```

请注意，一个可调用对象（省略括号）被传递给 `default`，而不是 `UUID` 的实例。

> **PostgreSQL 和 MariaDB 10.7+ 上的查找**
>
> 在 PostgreSQL 上使用 [`iexact`](/zh-hans/5.2/ref/models/querysets/#std-fieldlookup-iexact)、[`contains`](/zh-hans/5.2/ref/models/querysets/#std-fieldlookup-contains)、[`icontains`](/zh-hans/5.2/ref/models/querysets/#std-fieldlookup-icontains)、[`startswith`](/zh-hans/5.2/ref/models/querysets/#std-fieldlookup-startswith)、[`istartswith`](/zh-hans/5.2/ref/models/querysets/#std-fieldlookup-istartswith)、[`endswith`](/zh-hans/5.2/ref/models/querysets/#std-fieldlookup-endswith) 或 [`iendswith`](/zh-hans/5.2/ref/models/querysets/#std-fieldlookup-iendswith) 查找对于没有连字符的值不起作用，因为 PostgreSQL 和 MariaDB 10.7+ 将它们存储在带连字符的 uuid 数据类型中。

## 关系字段

Django 还定义了一组表示关系的字段。

### `ForeignKey`

#### `class ForeignKey(to, on_delete, **options)`

多对一关系。需要两个位置参数：模型关联的类和 [`on_delete`](#django.db.models.ForeignKey.on_delete) 选项：

```
from django.db import models

class Manufacturer(models.Model):
    name = models.TextField()

class Car(models.Model):
    manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
```

第一个位置参数可以是具体模型类或对模型类的 [延迟引用](#lazy-relationships)。还支持 [递归关系](#recursive-relationships)，即模型与自身的关系。

有关第二个位置参数的详细信息，请参阅 [`ForeignKey.on_delete`](#django.db.models.ForeignKey.on_delete)。

在 `ForeignKey` 上会自动创建一个数据库索引。你可以通过设置 [`db_index`](#django.db.models.Field.db_index) 为 `False` 来禁用它。 如果你创建外键是为了保持一致性，而不是为了连接，或者你将创建一个替代性的索引，如部分索引或多列索引，你可能希望避免索引的开销。

#### 数据库表现

在幕后，Django 会在字段名称后附加 `"_id"` 以创建其数据库列名。在上面的示例中，`Car` 模型的数据库表将有一个 `manufacturer_id` 列。你可以通过指定 [`db_column`](#django.db.models.Field.db_column) 显式更改此名称，但是，你的代码永远不需要处理数据库列名（除非你编写自定义 SQL）。你将始终处理模型对象的字段名称。

#### 参数

[`ForeignKey`](#django.db.models.ForeignKey) 接受其他定义关系工作细节的参数。

#### `ForeignKey.on_delete`

当一个由 [`ForeignKey`](#django.db.models.ForeignKey) 引用的对象被删除时，Django 将模拟 [`on_delete`](#django.db.models.ForeignKey.on_delete) 参数所指定的 SQL 约束的行为。例如，如果你有一个可空的 [`ForeignKey`](#django.db.models.ForeignKey)，并且你希望当被引用的对象被删除时，它被设置为空：

```
user = models.ForeignKey(
    User,
    models.SET_NULL,
    blank=True,
    null=True,
)
```

`on_delete` 不会在数据库中创建 SQL 约束。支持数据库级联选项 [可能会在以后实施](https://code.djangoproject.com/ticket/21961)。

[`on_delete`](#django.db.models.ForeignKey.on_delete) 的可能值可以在 [`django.db.models`](/zh-hans/5.2/topics/db/models/#module-django.db.models) 中找到。

- #### `CASCADE`

  Cascade deletes. Django emulates the behavior of the SQL constraint `ON
  DELETE CASCADE` and also deletes the object containing the
  [`ForeignKey`](#django.db.models.ForeignKey).

  [`Model.delete()`](/zh-hans/5.2/ref/models/instances/#django.db.models.Model.delete) 在相关的模型上没有被调用，但是 `pre_delete` 和 `post_delete` 信号是为所有被删除的对象发送的。
- #### `PROTECT`

  通过引发 [`ProtectedError`](/zh-hans/5.2/ref/exceptions/#django.db.models.ProtectedError)，即 [`django.db.IntegrityError`](/zh-hans/5.2/ref/exceptions/#django.db.IntegrityError) 的子类，防止删除被引用对象。
- #### `RESTRICT`

  通过引发 [`RestrictedError`](/zh-hans/5.2/ref/exceptions/#django.db.models.RestrictedError) （ [`django.db.IntegrityError`](/zh-hans/5.2/ref/exceptions/#django.db.IntegrityError) 的一个子类）来防止删除被引用的对象。与 [`PROTECT`](#django.db.models.PROTECT) 不同的是，如果被引用的对象也引用了一个在同一操作中被删除的不同对象，但通过 [`CASCADE`](#django.db.models.CASCADE) 关系，则允许删除被引用的对象。

  思考下下面这组模型：

  ```
  class Artist(models.Model):
      name = models.CharField(max_length=10)

  class Album(models.Model):
      artist = models.ForeignKey(Artist, on_delete=models.CASCADE)

  class Song(models.Model):
      artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
      album = models.ForeignKey(Album, on_delete=models.RESTRICT)
  ```

  `Artist` 可以被删除，即使这意味着删除一个被 `Song` 引用的 `Album`，因为 `Song` 也通过级联关系引用了 `Artist` 本身。例如：

  ```pycon
  >>> artist_one = Artist.objects.create(name="artist one")
  >>> artist_two = Artist.objects.create(name="artist two")
  >>> album_one = Album.objects.create(artist=artist_one)
  >>> album_two = Album.objects.create(artist=artist_two)
  >>> song_one = Song.objects.create(artist=artist_one, album=album_one)
  >>> song_two = Song.objects.create(artist=artist_one, album=album_two)
  >>> album_one.delete()
  # Raises RestrictedError.
  >>> artist_two.delete()
  # Raises RestrictedError.
  >>> artist_one.delete()
  (4, {'Song': 2, 'Album': 1, 'Artist': 1})
  ```
- #### `SET_NULL`

  设置 [`ForeignKey`](#django.db.models.ForeignKey) 为空；只有当 [`null`](#django.db.models.Field.null) 为 `True` 时，才有可能。
- #### `SET_DEFAULT`

  将 [`ForeignKey`](#django.db.models.ForeignKey) 设置为默认值，必须为 [`ForeignKey`](#django.db.models.ForeignKey) 设置一个默认值。
- #### `SET()`

  将 [`ForeignKey`](#django.db.models.ForeignKey) 设置为传递给 [`SET()`](#django.db.models.SET) 的值，或者如果传递的是可调用对象，则调用它的结果。在大多数情况下，传递可调用对象将是必要的，以避免在导入 `models.py` 时执行查询：

  ```
  from django.conf import settings
  from django.contrib.auth import get_user_model
  from django.db import models

  def get_sentinel_user():
      return get_user_model().objects.get_or_create(username="deleted")[0]

  class MyModel(models.Model):
      user = models.ForeignKey(
          settings.AUTH_USER_MODEL,
          on_delete=models.SET(get_sentinel_user),
      )
  ```
- #### `DO_NOTHING`

  不采取任何行动。如果你的数据库后端强制执行引用完整性，这将导致一个 [`IntegrityError`](/zh-hans/5.2/ref/exceptions/#django.db.IntegrityError) 除非你手动添加一个 SQL `ON DELETE` 约束条件到数据库字段。

#### `ForeignKey.limit_choices_to`

当使用 `ModelForm` 或管理中渲染该字段时，设置该字段的可用选择限制（默认情况下，查询集中的所有对象都可以选择）。可以使用字典、 [`Q`](/zh-hans/5.2/ref/models/querysets/#django.db.models.Q) 对象，或者返回字典或 [`Q`](/zh-hans/5.2/ref/models/querysets/#django.db.models.Q) 对象的可调用对象。

例子：

```
staff_member = models.ForeignKey(
    User,
    on_delete=models.CASCADE,
    limit_choices_to={"is_staff": True},
)
```

causes the corresponding field on the `ModelForm` to list only `User`
instances that have `is_staff=True`. This may be helpful in the Django
admin.

例如，当与 Python `datetime` 模块一起使用时，可调用对象可以很有帮助，通过日期范围限制选择。例如：

```
def limit_pub_date_choices():
    return {"pub_date__lte": datetime.date.today()}

limit_choices_to = limit_pub_date_choices
```

如果 `limit_choices_to` 是或返回一个 [`Q对象`](/zh-hans/5.2/ref/models/querysets/#django.db.models.Q)，这对 [复杂的查询](/zh-hans/5.2/topics/db/queries/#complex-lookups-with-q) 很有用，那么只有当该字段没有在 `ModelAdmin` 中的 [`raw_id_fields`](/zh-hans/5.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.raw_id_fields) 中列出时，它才会对管理中可用的选择产生影响。

> **Note**
>
> 如果 `limit_choices_to` 使用了可调用对象，那么每次实例化一个新的表单时，都会调用该功能。它也可以在模型被验证时被调用，例如由管理命令或管理中调用。管理中构建查询集来多次验证各种边缘情况下的表单输入，所以你的可调用对象有可能会被多次调用。

#### `ForeignKey.related_name`

用于从相关对象到这个对象的关系的名称。这也是 [`related_query_name`](#django.db.models.ForeignKey.related_query_name) 的默认值（用于从目标模型反向过滤名称的名称）。请参阅 [关联对象文档](/zh-hans/5.2/topics/db/queries/#backwards-related-objects) 以获得完整的解释和示例。请注意，当你在 抽象模型 是可用的。

如果你不希望 Django 创建一个反向关系，可以将 `related_name` 设置为 `'+'` 或者以 `'+'` 结束。例如，这将确保 `User` 模型不会与这个模型有反向关系：

```
user = models.ForeignKey(
    User,
    on_delete=models.CASCADE,
    related_name="+",
)
```

#### `ForeignKey.related_query_name`

目标模型中反向过滤器的名称。如果设置了，它默认为 [`related_name`](#django.db.models.ForeignKey.related_name) 或 [`default_related_name`](/zh-hans/5.2/ref/models/options/#django.db.models.Options.default_related_name) 的值，否则默认为模型的名称：

```
# Declare the ForeignKey with related_query_name
class Tag(models.Model):
    article = models.ForeignKey(
        Article,
        on_delete=models.CASCADE,
        related_name="tags",
        related_query_name="tag",
    )
    name = models.CharField(max_length=255)

# That's now the name of the reverse filter
Article.objects.filter(tag__name="important")
```

和 [`related_name`](#django.db.models.ForeignKey.related_name) 一样，`related_query_name` 通过 [一些特殊的语法](/zh-hans/5.2/topics/db/models/#abstract-related-name) 支持应用标签和类的插值。

#### `ForeignKey.to_field`

关联对象的字段。默认情况下，Django 使用相关对象的主键。如果你引用了一个不同的字段，这个字段必须有 `unique=True`。

#### `ForeignKey.db_constraint`

控制是否应该在数据库中为这个外键创建一个约束。默认值是 `True`，这几乎是你想要的；将其设置为 `False` 对数据完整性非常不利。话虽如此，下面是一些你可能想要这样做的情况：

- 你有无效的冗余数据
- 你正在共享你的数据库

如果将此设置为 `False`，访问一个不存在的相关对象将引发 `DoesNotExist` 异常。

#### `ForeignKey.swappable`

控制迁移框架的反应，如果这个 [`ForeignKey`](#django.db.models.ForeignKey) 指向一个可交换的模型。如果它是 `True` ——默认值-——那么如果 [`ForeignKey`](#django.db.models.ForeignKey) 指向的模型与 `settings.AUTH_USER_MODEL` 的当前值相匹配（或其他可互换模型配置），则关系将在迁移中使用对配置的引用而不是直接对模型进行存储。

只有当你确定你的模型应该总是指向换入的模型时，你才想把它覆盖为 `False`，例如，如果它是一个专门为你的自定义用户模型设计的配置文件模型。

Setting it to `False` does not mean you can reference a swappable model
even if it is swapped out - `False` means that the migrations made
with this [`ForeignKey`](#django.db.models.ForeignKey) will always reference the exact model you
specify (so it will fail hard if the user tries to run with a `User`
model you don't support, for example).

如果不确定，就保留它在默认为 `True` 的状态。

### `ManyToManyField`

#### `class ManyToManyField(to, **options)`

一个多对多的关系。需要一个位置参数：模型相关的类，它的工作原理与 [`ForeignKey`](#django.db.models.ForeignKey) 完全相同，包括 [递归](#recursive-relationships) 和 [惰性](#lazy-relationships) 关系。

可以通过字段的 `RelatedManager` 来添加、删除或创建相关对象。

#### 数据库表现

在幕后，Django 创建了一个中间连接表来表示多对多的关系。默认情况下，这个表名是使用多对多字段的名称和包含它的模型的表名生成的。由于有些数据库不支持超过一定长度的表名，这些表名将被自动截断，并使用唯一性哈希，例如 `author_books_9cdf`。你可以使用 [`db_table`](#django.db.models.ManyToManyField.db_table) 选项手动提供连接表的名称。

#### 参数

[`ManyToManyField`](#django.db.models.ManyToManyField) 接受一组额外的参数——都是可选的——控制关系如何运作。

#### `ManyToManyField.related_name`

与 [`ForeignKey.related_name`](#django.db.models.ForeignKey.related_name) 相同。

#### `ManyToManyField.related_query_name`

与 [`ForeignKey.related_query_name`](#django.db.models.ForeignKey.related_query_name) 相同。

#### `ManyToManyField.limit_choices_to`

与 [`ForeignKey.limit_choices_to`](#django.db.models.ForeignKey.limit_choices_to) 相同。

#### `ManyToManyField.symmetrical`

仅在自身上定义多对多字段关系时。考虑以下模型

```
from django.db import models

class Person(models.Model):
    friends = models.ManyToManyField("self")
```

当 Django 处理这个模型时，它识别出它本身有一个 [`ManyToManyField`](#django.db.models.ManyToManyField)，因此，它没有给 `Person` 类添加 `person_set` 属性。相反， [`ManyToManyField`](#django.db.models.ManyToManyField) 被认为是对称的，也就是说，如果我是你的朋友，那么你就是我的朋友。

如果你不想让 `self` 的多对多关系对称，可以将 [`symmetrical`](#django.db.models.ManyToManyField.symmetrical) 设置为 `False`。这样会强制 Django 添加反向关系的描述符，允许 [`ManyToManyField`](#django.db.models.ManyToManyField) 关系是非对称的。

#### `ManyToManyField.through`

Django 会自动生成一个表来管理多对多关系。但是，如果你想手动指定中间表，你可以使用 [`through`](#django.db.models.ManyToManyField.through) 选项来指定代表你要使用的中间表的 Django 模型。

The `through` model can be specified using either the model class
directly or a [lazy reference](#lazy-relationships) to the model
class.

这个选项最常见的用法是当你想把 [额外的数据与多对多关系](/zh-hans/5.2/topics/db/models/#intermediary-manytomany) 联系起来。

> **Note**
>
> 使用代理模型的递归关系不能确定反向访问器的名称，因为它们会是相同的。你需要设置一个 [`related_name`](#django.db.models.ForeignKey.related_name) 到其中至少一个。如果你希望 Django 不创建反向关系，请将 `related_name` 设置为 `'+'`。

> **Foreign key order in intermediary models**
>
> When defining an asymmetric many-to-many relationship from a model to
> itself using an intermediary model without defining
> [`through_fields`](#django.db.models.ManyToManyField.through_fields), the first foreign key in the intermediary model
> will be treated as representing the source side of the
> `ManyToManyField`, and the second as the target side. For example:
>
> ```
> from django.db import models
>
>
> class Manufacturer(models.Model):
>     name = models.CharField(max_length=255)
>     clients = models.ManyToManyField(
>         "self", symmetrical=False, related_name="suppliers", through="Supply"
>     )
>
>
> class Supply(models.Model):
>     supplier = models.ForeignKey(
>         Manufacturer, models.CASCADE, related_name="supplies_given"
>     )
>     client = models.ForeignKey(
>         Manufacturer, models.CASCADE, related_name="supplies_received"
>     )
>     product = models.CharField(max_length=255)
> ```
>
> Here, the `Manufacturer` model defines the many-to-many relationship
> with `clients` in its role as a supplier. Therefore, the `supplier`
> foreign key (the source) must come before the `client` foreign key
> (the target) in the intermediary `Supply` model.
>
> Specifying [`through_fields=("supplier", "client")`](#django.db.models.ManyToManyField.through_fields) on the `ManyToManyField` makes the
> order of foreign keys on the `through` model irrelevant.

If you don't specify an explicit `through` model, there is still an
implicit `through` model class you can use to directly access the table
created to hold the association. It has three fields to link the models, a
primary key and two foreign keys. There is a unique constraint on the two
foreign keys.

如果源模型和目标模型不同，则会生成以下字段：

- `id` ：关系的主键。
- `<containing_model>_id` ：声明 `ManyToManyField` 的模型的 `id`。
- `<other_model>_id` ：`ManyToManyField` 指向的模型的 `id`。

如果 `ManyToManyField` 指向的来源和目标是相同的模型， 下面的字段会生成：

- `id` ：关系的主键。
- `from_<model>_id` ：指向模型的实例（即源实例）的 `id`。
- `to_<model>_id` ：关系所指向的实例（即目标模型实例）的 `id`。

这个类可以像普通模型一样，用于查询给定模型实例的关联记录：

```
Model.m2mfield.through.objects.all()
```

#### `ManyToManyField.through_fields`

只有当指定了一个自定义的中间模型时才会使用，Django 通常会决定使用中介模型的哪些字段来自动建立多对多的关系。然而，考虑以下模型：

```
from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=50)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(
        Person,
        through="Membership",
        through_fields=("group", "person"),
    )

class Membership(models.Model):
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    inviter = models.ForeignKey(
        Person,
        on_delete=models.CASCADE,
        related_name="membership_invites",
    )
    invite_reason = models.CharField(max_length=64)
```

`Membership` 对 `Person` 有 *两个* 外键（ `person` 和 `inviter` ），这就使得两者的关系变得模糊不清，Django 无法知道应该使用哪个外键。在这种情况下，你必须使用 `through_fields` 明确指定 Django 应该使用哪个外键，就像上面的例子一样。

`through_fields` 接受一个二元元组 `('field1', 'field2')`，其中 `field1` 是定义在 [`ManyToManyField`](#django.db.models.ManyToManyField) 上的模型（本例中为 `group` ）的外键名称，`field2` 是目标模型（本例中为 `person` ）的外键名称。

当你在中间模型上有一个以上的外键到任何一个（甚至两个）参与多对多关系的模型时，你 *必须* 指定 `through_fields`。这也适用于 [递归关系](#recursive-relationships)，当使用一个中间模型，并且该模型有两个以上的外键，或者你想明确指定 Django 应该使用哪两个外键。

#### `ManyToManyField.db_table`

要创建的用于存储多对多数据的表的名称。如果没有提供这个表名，Django 将根据以下表名创建一个默认表名：定义关系的模型表和字段本身的名称。

#### `ManyToManyField.db_constraint`

控制是否应该在数据库中为中间表的外键创建约束。默认值是 `True`，这几乎是你想要的；将其设置为 `False` 对数据完整性非常不利。话说回来，下面是一些你可能想要这样做的情况：

- 你有无效的冗余数据
- 你正在共享你的数据库

同时传递 `db_constraint` 和 `through` 会引发错误。

#### `ManyToManyField.swappable`

控制迁移框架的反应，如果这个 [`ManyToManyField`](#django.db.models.ManyToManyField) 指向一个可交换的模型。如果它是 `True` ——默认值——那么如果 [`ManyToManyField`](#django.db.models.ManyToManyField) 指向的模型与 `settings.AUTH_USER_MODEL` 的当前值相匹配（或其他可交换模型配置），关系将被存储在迁移中，使用对配置的引用，而不是直接对模型的引用。

只有当你确定你的模型应该总是指向换入的模型时，你才想把它覆盖为 `False`，例如，如果它是一个专门为你的自定义用户模型设计的配置文件模型。

如果不确定，就保留它在默认为 `True` 的状态。

[`ManyToManyField`](#django.db.models.ManyToManyField) 不支持 [`validators`](#django.db.models.Field.validators)。

[`null`](#django.db.models.Field.null) 没有效果，因为没有办法在数据库层面要求建立关系。

### `OneToOneField`

#### `class OneToOneField(to, on_delete, parent_link=False, **options)`

一对一的关系。概念上，这类似于 [`ForeignKey`](#django.db.models.ForeignKey) 与 [`unique=True`](#django.db.models.Field.unique)，但关系的“反向”将直接返回一个单一对象。

最有用的是作为某种方式“扩展”另一个模型的主键；[多表继承](/zh-hans/5.2/topics/db/models/#multi-table-inheritance) 是通过添加一个从子模型到父模型的隐式一对一关系来实现的，例如：

需要一个位置参数：模型将与之相关的类。这与 [`ForeignKey`](#django.db.models.ForeignKey) 的工作原理完全相同，包括关于 [递归](#recursive-relationships) 和 [惰性](#lazy-relationships) 关系的所有选项。

如果没有为 `OneToOneField` 指定 [`related_name`](#django.db.models.ForeignKey.related_name) 参数，Django 将使用当前模型的小写名作为默认值。

举例如下：

```
from django.conf import settings
from django.db import models

class MySpecialUser(models.Model):
    user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )
    supervisor = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
        related_name="supervisor_of",
    )
```

你的最终 `User` 模型将具有以下属性：

```pycon
>>> user = User.objects.get(pk=1)
>>> hasattr(user, "myspecialuser")
True
>>> hasattr(user, "supervisor_of")
True
```

在访问反向关系时，如果相关表中的条目不存在，将引发 `RelatedObjectDoesNotExist` 异常。这是目标模型的 [`Model.DoesNotExist`](/zh-hans/5.2/ref/models/class/#django.db.models.Model.DoesNotExist) 异常的子类，可以作为反向访问器的属性访问。例如，如果用户没有由 `MySpecialUser` 指定的主管：

```
try:
    user.supervisor_of
except User.supervisor_of.RelatedObjectDoesNotExist:
    pass
```

此外，`OneToOneField` 接受 [`ForeignKey`](#django.db.models.ForeignKey) 接受的所有额外参数，外加一个额外参数：

#### `OneToOneField.parent_link`

当 `True` 并用于从另一个 [concrete model](/zh-hans/5.2/glossary/#term-concrete-model) 继承的模型中时，表示该字段应被用作回到父类的链接，而不是通常通过子类隐含创建的额外 `OneToOneField`。

参见 [一对一关系](/zh-hans/5.2/topics/db/examples/one_to_one/)，了解 `OneToOneField` 的使用实例。

### 延迟关系

延迟关系允许通过模型名称（作为字符串）引用模型或创建递归关系。字符串可以用作任何关系字段的第一个参数，以延迟引用模型。延迟引用可以是 [递归](#recursive-relationships)、[相对](#relative-relationships) 或 [绝对](#absolute-relationships)。

#### 递归

要定义一个模型引用自身的关系，请使用 `"self"` 作为关系字段的第一个参数：

```
from django.db import models

class Manufacturer(models.Model):
    name = models.TextField()
    suppliers = models.ManyToManyField("self", symmetrical=False)
```

当在 [抽象模型](/zh-hans/5.2/topics/db/models/#abstract-base-classes) 中使用时，递归关系会解析为每个具体子类引用自身。

#### 相对

当需要与尚未定义的模型建立关系时，可以通过其名称而不是模型对象本身来引用它：

```
from django.db import models

class Car(models.Model):
    manufacturer = models.ForeignKey(
        "Manufacturer",
        on_delete=models.CASCADE,
    )

class Manufacturer(models.Model):
    name = models.TextField()
    suppliers = models.ManyToManyField("self", symmetrical=False)
```

在 [抽象模型](/zh-hans/5.2/topics/db/models/#abstract-base-classes) 上以这种方式定义的关系在模型被子类化为具体模型时得到解析，与抽象模型的 `app_label` 不是相关的：

*`products/models.py`*

```python
from django.db import models

class AbstractCar(models.Model):
    manufacturer = models.ForeignKey("Manufacturer", on_delete=models.CASCADE)

    class Meta:
        abstract = True
```

*`production/models.py`*

```python
from django.db import models
from products.models import AbstractCar

class Manufacturer(models.Model):
    name = models.TextField()

class Car(AbstractCar):
    pass
```

在此示例中，`Car.manufacturer` 关系将解析为 `production.Manufacturer`，因为它指向在 `production/models.py` 文件中定义的具体模型。

> **具有相对引用的可重用模型**
>
> 相对引用允许创建具有关系的可重用抽象模型，这些关系可以解析为不同应用程序中各个子类的引用模型的不同实现。

#### 绝对

绝对引用使用模型的 `app_label` 和类名指定模型，允许跨不同应用程序的模型引用。这种类型的延迟关系还可以帮助解决循环导入问题。

例如，如果 `Manufacturer` 模型在另一个名为 `thirdpartyapp` 的应用程序中定义，则可以引用为：

```
class Car(models.Model):
    manufacturer = models.ForeignKey(
        "thirdpartyapp.Manufacturer",
        on_delete=models.CASCADE,
    )
```

绝对引用始终指向同一个模型，即使在 [抽象模型](/zh-hans/5.2/topics/db/models/#abstract-base-classes) 中使用时也是如此。

## 字段 API 参考

#### `class Field`

`Field` 是一个抽象的类，表示一个数据库表的列。Django 使用字段来创建数据库表（ [`db_type()`](#django.db.models.Field.db_type) ），将 Python 类型映射到数据库（ [`get_prep_value()`](#django.db.models.Field.get_prep_value) ），反之亦然（ [`from_db_value()`](#django.db.models.Field.from_db_value) ）。

因此，一个字段在不同的 Django API 中是一个基本的部分，特别是 [`models`](/zh-hans/5.2/ref/models/instances/#django.db.models.Model) 和 [`querysets`](/zh-hans/5.2/ref/models/querysets/#django.db.models.query.QuerySet)。

在模型中，字段被实例化为一个类属性，并代表一个特定的表列，见 [模型](/zh-hans/5.2/topics/db/models/)。它的属性有 [`null`](#django.db.models.Field.null) 和 [`unique`](#django.db.models.Field.unique)，以及 Django 用来将字段值映射到数据库特定值的方法。

`Field` 是 [`RegisterLookupMixin`](/zh-hans/5.2/ref/models/lookups/#django.db.models.lookups.RegisterLookupMixin) 的子类，因此 [`Transform`](/zh-hans/5.2/ref/models/lookups/#django.db.models.Transform) 和 [`Lookup`](/zh-hans/5.2/ref/models/lookups/#django.db.models.Lookup) 都可以在它上面注册，以便在 `QuerySet` 中使用（例如： `field_name__exact="foo"` ）。所有 [内置查找](/zh-hans/5.2/ref/models/querysets/#field-lookups) 都是默认注册的。

所有 Django 的内置字段，如 [`CharField`](#django.db.models.CharField)，都是 `Field` 的特殊实现。如果你需要一个自定义的字段，你可以对任何一个内置字段进行子类化，或者从头开始写一个 `Field`。无论哪种情况，请参见 [编写自定义模型字段](/zh-hans/5.2/howto/custom-model-fields/)。

#### `description`

字段的详细描述，例如： [`django.contrib.admindocs`](/zh-hans/5.2/ref/contrib/admin/admindocs/#module-django.contrib.admindocs) 应用程序。

描述的形式可以是：

```
description = _("String (up to %(max_length)s)")
```

其中的参数是从字段的 `__dict__` 中插入的。

#### `descriptor_class`

一个实现 [描述符协议](https://docs.python.org/3/reference/datamodel.html#descriptors) 的类，它被实例化并分配给模型实例属性。构造函数必须接受一个参数，即 `Field` 实例。覆盖该类属性可以自定义获取和设置行为。

为了将一个 `Field` 映射到数据库的特定类型，Django 提供了一些方法：

#### `get_internal_type()`

返回一个字符串，用于命名这个字段，以满足后台的特定目的。默认情况下，它返回的是类名。

参见 [仿造内置字段类型](/zh-hans/5.2/howto/custom-model-fields/#emulating-built-in-field-types) 在自定义字段中的用法。

#### `db_type(connection)`

根据 `connection`， 返回 [`Field`](#django.db.models.Field) 的数据库列数据类型。

参见 [自定义数据库类型](/zh-hans/5.2/howto/custom-model-fields/#custom-database-types) 在自定义字段中的用法。

#### `rel_db_type(connection)`

返回指向 [`Field`](#django.db.models.Field) 的 `ForeignKey` 和 `OneToOneField` 等字段的数据库列数据类型，并考虑 `connection`。

参见 [自定义数据库类型](/zh-hans/5.2/howto/custom-model-fields/#custom-database-types) 在自定义字段中的用法。

Django 主要有三种情况需要与数据库后台和字段进行交互。

- 当它查询数据库时（Python 值 -\> 数据库后台值）
- 当它从数据库中加载数据时（数据库后台值 -\> Python 值）
- 当它保存到数据库时（Python 值 -\> 数据库后端值）

查询时，使用 [`get_db_prep_value()`](#django.db.models.Field.get_db_prep_value) 和 [`get_prep_value()`](#django.db.models.Field.get_prep_value)。

#### `get_prep_value(value)`

`value` 是模型属性的当前值，该方法应以准备作为查询参数的格式返回数据。

见 [将 Python 转为查询值](/zh-hans/5.2/howto/custom-model-fields/#converting-python-objects-to-query-values) 的用法。

#### `get_db_prep_value(value, connection, prepared=False)`

将 `value` 转换为后台特定的值，默认情况下，如果 `prepared=True`，它将返回 `value`。而如果是 `False`，它将返回 [`get_prep_value()`](#django.db.models.Field.get_prep_value) 。

使用方法参见 [将查询值转为数据库值](/zh-hans/5.2/howto/custom-model-fields/#converting-query-values-to-database-values)。

加载数据时，使用 [`from_db_value()`](#django.db.models.Field.from_db_value)。

#### `from_db_value(value, expression, connection)`

将数据库返回的值转换为 Python 对象。与 [`get_prep_value()`](#django.db.models.Field.get_prep_value) 相反。

这个方法不用于大多数内置字段，因为数据库后端已经返回了正确的 Python 类型，或者后端自己进行了转换。

`expression` 与 `self` 相同。

使用方法参见 [将值转为 Python 对象](/zh-hans/5.2/howto/custom-model-fields/#converting-values-to-python-objects)。

> **Note**
>
> 由于性能原因，`from_db_value` 并没有在不需要它的字段上实现 no-op（所有 Django 字段）。因此，你不能在定义中调用 `super`。

保存时，使用 [`pre_save()`](#django.db.models.Field.pre_save) 和 [`get_db_prep_save()`](#django.db.models.Field.get_db_prep_save) ：

#### `get_db_prep_save(value, connection)`

与 [`get_db_prep_value()`](#django.db.models.Field.get_db_prep_value) 相同，但当字段值必须 *保存* 到数据库中时，会被调用。默认情况下返回 [`get_db_prep_value()`](#django.db.models.Field.get_db_prep_value)。

#### `pre_save(model_instance, add)`

在 [`get_db_prep_save()`](#django.db.models.Field.get_db_prep_save) 之前调用的方法，在保存前准备好值（例如 [`DateField.auto_now`](#django.db.models.DateField.auto_now) ）。

`model_instance` 是该字段所属的实例，`add` 是该实例是否第一次被保存到数据库中。

它应该从 `model_instance` 中返回这个字段的适当属性的值。属性名在 `self.attname` 中（这是由 [`Field`](#django.db.models.Field) 设置的）。

使用方法参见 [在保存前预处理数值](/zh-hans/5.2/howto/custom-model-fields/#preprocessing-values-before-saving)。

字段经常以不同的类型接收它们的值，要么来自序列化，要么来自表单。

#### `to_python(value)`

将值转换为正确的 Python 对象。它的作用与 [`value_to_string()`](#django.db.models.Field.value_to_string) 相反，并且在 [`clean()`](/zh-hans/5.2/ref/models/instances/#django.db.models.Model.clean) 中也被调用。

使用方法参见 [将值转为 Python 对象](/zh-hans/5.2/howto/custom-model-fields/#converting-values-to-python-objects)。

除了保存到数据库，字段还需要知道如何将其值序列化。

#### `value_from_object(obj)`

返回给定模型实例的字段值。

这个方法经常被 [`value_to_string()`](#django.db.models.Field.value_to_string) 使用。

#### `value_to_string(obj)`

将 `obj` 转换为字符串。用于序列化字段的值。

使用方法参见 [为序列化转换字段数据](/zh-hans/5.2/howto/custom-model-fields/#converting-model-field-to-serialization)。

当使用 [`model forms`](/zh-hans/5.2/topics/forms/modelforms/#django.forms.ModelForm) 时，`Field` 需要知道它应该由哪个表单字段来表示。

#### `formfield(form_class=None, choices_form_class=None, **kwargs)`

返回该字段默认的 [`django.forms.Field`](/zh-hans/5.2/ref/forms/fields/#django.forms.Field) 给 [`ModelForm`](/zh-hans/5.2/topics/forms/modelforms/#django.forms.ModelForm)。

If [`formfield()`](#django.db.models.Field.formfield) is overridden to return `None`, this field
is excluded from the [`ModelForm`](/zh-hans/5.2/topics/forms/modelforms/#django.forms.ModelForm).

默认情况下，如果 `form_class` 和 `choices_form_class` 都是 `None`，则使用 [`CharField`](/zh-hans/5.2/ref/forms/fields/#django.forms.CharField)。如果字段有 `chips`，且 `choices_form_class` 没有指定，则使用 [`TypedChoiceField`](/zh-hans/5.2/ref/forms/fields/#django.forms.TypedChoiceField)。

使用方法参见 [为模型字段指定表单字段](/zh-hans/5.2/howto/custom-model-fields/#specifying-form-field-for-model-field)。

#### `deconstruct()`

返回一个包含足够信息的四元元组来重新创建字段。

1. 模型上的字段名称。
2. 字段的导入路径（例如 `"django.db.models.IntegerField"` ）。这应该是最可移植版本，所以不那么具体可能更好。
3. 一个位置参数的列表。
4. 一个关键字参数的字典。

这个方法必须添加到 1.7 之前的字段中，才能使用 [迁移](/zh-hans/5.2/topics/migrations/) 迁移其数据。

## 注册和获取查询

`Field` 实现了 [查找注册 API](/zh-hans/5.2/ref/models/lookups/#lookup-registration-api)。该 API 可以用于自定义哪些查找适用于字段类及其实例，以及如何从字段中获取查找。

# 字段属性参考

每个 `Field` 实例都包含几个属性，允许对其行为进行内省。当你需要编写依赖于字段功能的代码时，可以使用这些属性来代替 `isinstance` 检查。这些属性可以与 [Model.\_meta API](/zh-hans/5.2/ref/models/meta/#model-meta-field-api) 一起使用，以缩小对特定字段类型的搜索范围。自定义模型字段应该实现这些标志。

## 字段的属性

#### `Field.auto_created`

表示是否自动创建字段的布尔标志，如模型继承使用的 `OneToOneField`。

#### `Field.concrete`

布尔值标志，表示该字段是否有与之相关的数据库列。

#### `Field.hidden`

布尔标志，指示字段是否隐藏，并且默认情况下不应由 [`Options.get_fields()`](/zh-hans/5.2/ref/models/meta/#django.db.models.options.Options.get_fields) 返回。一个示例是对于一个以 `'+'` 开头的 `related_name` 的 [`ForeignKey`](#django.db.models.ForeignKey) 的反向字段。

#### `Field.is_relation`

布尔值标志，表示一个字段是否包含对一个或多个其他模型的功能引用（如 `ForeignKey`、`ManyToManyField`、`OneToOneField` 等）。

#### `Field.model`

返回定义字段的模型。如果一个字段定义在一个模型的超类上，`model` 将指的是超类，而不是实例的类。

## 有关系的字段的属性

这些属性用于查询关系的基数和其他细节。这些属性在所有字段上都存在；但是，如果字段是关系类型（ [`Field.is_relation=True`](#django.db.models.Field.is_relation) ），它们只有布尔值（而不是 `None` ）。

#### `Field.many_to_many`

如果字段有多对多关系，则为 `True`，否则为 `False`。Django 中唯一一个是 `True` 的字段是 `ManyToManyField`。

#### `Field.many_to_one`

如果字段有多对一关系，如 `ForeignKey`，则为 `True` ；否则为 `False`。

#### `Field.one_to_many`

如果该字段有一对多关系，如 `GenericRelation` 或 `ForeignKey` 的反向关系，则为 `True` ；否则为 `False`。

#### `Field.one_to_one`

如果字段有一对一的关系，如 `OneToOneField`，则为 `True` ；否则为 `False`。

#### `Field.related_model`

指向该字段所涉及的模型。例如，`ForeignKey(Author, on_delete=models.CASCADE)` 中的 `Author`。`GenericForeignKey` 的 `related_model` 总是 `None`。
