# Django 3.2.11.dev 文档

# 模型字段参考

本文档包含 `Field` 类的所有 API 参考，包括 字段选项 和 字段类型。

参见

若内置字段未满足需求，你可以试试 django-localflavor （ 文档 ），它包含了针对各别国家和文件的代码。

当然，你也可以简单的 编写自定义模型字段。

注解

从技术上讲，这些方法都被定义在 `django.db.models.fields`，但为了方便，它们被导入到 `django.db.models`；标准的惯例是使用 `from django.db import models` 并利用 `models.<Foo>Field`。

## 字段选项

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

### `null`

`Field.``null`

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

避免在基于字符串的字段上使用 `null`，如 `CharField` 和 `TextField`。如果一个基于字符串的字段有 `null=True`，这意味着它有两种可能的“无数据”值。`NULL`，和空字符串。在大多数情况下，“无数据”有两种可能的值是多余的，Django 的惯例是使用空字符串，而不是 `NULL`。一个例外是当一个 `CharField` 同时设置了 `unique=True` 和 `blank=True`。在这种情况下，`null=True` 是需要的，以避免在保存具有空白值的多个对象时违反唯一约束。

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

注解

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

### `blank`

`Field.``blank`

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

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

### `choices`

`Field.``choices`

一个 sequence 本身由正好两个项目的迭代项组成（例如 `[(A，B)，(A，B)...]` ），作为该字段的选择。如果给定了选择，它们会被 模型验证 强制执行，默认的表单部件将是一个带有这些选择的选择框，而不是标准的文本字段。

每个元组中的第一个元素是要在模型上设置的实际值，第二个元素是人可读的名称。例如：

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

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

    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'` 选项）。

对于每一个设置了 `choice` 的模型字段，Django 会添加一个方法来检索字段当前值的可读名称。参见数据库 API 文档中的 `get_FOO_display()`。

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

注解

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

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

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

这些工作类似于 Python 标准库中的 `enum`，但是做了一些修改。

- 枚举成员值是构造具体数据类型时要使用的参数元组。Django 支持在这个元组的末尾添加一个额外作为人可读的名称的字符串值 `label`。`label` 可以是一个惰性的可翻译字符串。因此，在大多数情况下，成员值将是一个 `(value, label)` 二元组。请看下面使用更复杂的数据类型 子类化选择的例子。如果没有提供元组，或者最后一项不是（惰性）字符串，`label` 是从成员名 自动生成。
- 在值上添加 `.label` 属性，以返回人类可读的名称。
- 在枚举类中添加了一些自定义属性—— `.choice`、`.labs`、`.values` 和 `.names` ——以便于访问枚举的这些单独部分的列表。在字段定义中，使用 `.choice` 作为一个合适的值传递给 `choice`。
- 强制使用 `enum.unique()` 是为了确保不能多次定义值。在选择一个字段时，不太可能会出现这种情况。

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

如果你不需要翻译成人名，你可以从成员名称中推断出这些名称（用空格代替下划线并使用标题大小写）：

    >>> 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.choices)

也可以使用 Enum Functional API ，但需要注意的是，标签是自动生成的，如上文所强调的：

    >>> 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` 与 `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)'

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

- 枚举类型不支持 命名组。

- 因为具有具体数据类型的枚举要求所有值都与类型相匹配，所以不能通过创建一个值为 `None` 的成员来覆盖 空白标签。相反，在类上设置 `__empty__` 属性：

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

          __empty__ = _('(Unknown)')

### `db_column`

`Field.``db_column`

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

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

### `db_index`

`Field.``db_index`

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

### `db_tablespace`

`Field.``db_tablespace`

如果这个字段有索引，那么要为这个字段的索引使用的 数据库表空间 的名称。默认是项目的 `DEFAULT_INDEX_TABLESPACE` 设置（如果有设置），或者是模型的 `db_tablespace` （如果有）。如果后端不支持索引的表空间，则忽略此选项。

### `default`

`Field.``default`

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

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

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

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

`lambda` 不能用于 `default` 等字段选项，因为它们不能被 迁移序列化。其他注意事项见该文档。

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

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

### `editable`

`Field.``editable`

如果是 `False`，该字段将不会在管理或任何其他 `ModelForm` 中显示。在 模型验证 中也会跳过。默认为 `True`。

### `error_messages`

`Field.``error_messages`

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

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

这些错误信息通常不会传播到表单中。参见 有关模型的 error_messages 的注意事项。

### `help_text`

`Field.``help_text`

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

请注意，在自动生成的表格中，这个值 不是 HTML 转义的。如果你愿意的话，你可以在 `help_text` 中加入 HTML。例如：

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

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

### `primary_key`

`Field.``primary_key`

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

如果你没有为模型中的任何字段指定 `primary_key=True`，Django 会自动添加一个字段来保存主键，所以你不需要在任何字段上设置 primary_key=True，除非你想覆盖默认主键行为。自动创建的主键字段的类型可以在 `AppConfig.default_auto_field` 中为每个应用程序指定，或者在 `DEFAULT_AUTO_FIELD` 配置中全局指定。更多信息，请参阅 自动设置主键。

`primary_key=True` 意味着 `null=False` 和 `unique=True`。一个对象只允许有一个主键。

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

Changed in Django 3.2:

在旧版本中，自动创建的主键字段总是 `AutoField`。

### `unique`

`Field.``unique`

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

这是在数据库级别和模型验证中强制执行的。如果你试图保存一个在 `unique` 字段中存在重复值的模型，模型的 `save()` 方法将引发 `django.db.IntegrityError`。

除了 `ManyToManyField` 和 `OneToOneField` 之外，该选项对所有字段类型有效。

请注意，当 `unique` 为 `True` 时，你不需要指定 `db_index`，因为 `unique` 意味着创建一个索引。

### `unique_for_date`

`Field.``unique_for_date`

将其设置为 `DateField` 或 `DateTimeField` 的名称，要求该字段的日期字段值是唯一的。

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

请注意，如果将其设置为指向 `DateTimeField`，则只考虑该字段的日期部分。此外，当 `USE_TZ` 为 `True` 时，检查将在对象保存时的 当前时区 中进行。

这在模型验证过程中由 `Model.validate_unique()` 强制执行，但在数据库级别上不执行。如果任何 `unique_for_date` 约束涉及的字段不属于 `ModelForm` （例如，如果其中一个字段被列在``exclude``中，或者有 `editable=False` ）， `Model.validate_unique()` 将跳过对该特定约束的验证。

### `unique_for_month`

`Field.``unique_for_month`

像 `unique_for_date` 一样，但要求字段对月份是唯一的。

### `unique_for_year`

`Field.``unique_for_year`

如 `unique_fordate` 和 `unique_formonth`。

### `verbose_name`

`Field.``verbose_name`

字段的一个人类可读名称，如果没有给定详细名称，Django 会使用字段的属性名自动创建，并将下划线转换为空格。参见 详细字段名。

### `validators`

`Field.``validators`

要为该字段运行的验证器列表。更多信息请参见 验证器文档。

#### 注册和获取查询

`Field` 实现了 查询注册 API。该 API 可用于自定义字段类的哪些查询是可用的，以及如何从字段中获取查询。

## 字段类型

### `AutoField`

class `AutoField`(**options)

一个 `IntegerField`，根据可用的 ID 自动递增。你通常不需要直接使用它；如果你没有指定，主键字段会自动添加到你的模型中。参见 自动设置主键。

### `BigAutoField`

class `BigAutoField`(**options)

一个 64 位整数，与 `AutoField` 很相似，但保证适合 `1` 到 `9223372036854775807` 的数字。

### `BigIntegerField`

class `BigIntegerField`(**options)

一个 64 位的整数，和 `IntegerField` 很像，只是它保证适合从 `-9223372036854775808` 到 `9223372036854775807` 的数字。该字段的默认表单部件是一个 `NumberInput`。

### `BinaryField`

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

一个用于存储原始二进制数据的字段。可以指定为 `bytes`、`bytearray` 或 `memoryview`。

默认情况下，`BinaryField` 将 `ediditable`` 设置为 `False`，在这种情况下，它不能被包含在 `ModelForm` 中。

`BinaryField` 有一个额外的可选参数：

`BinaryField.``max_length`

  The maximum length (in bytes) of the field. The maximum length is enforced in Django's validation using `MaxLengthValidator`.

滥用 `BinaryField`

虽然你可能会想到在数据库中存储文件，但考虑到这在99%的情况下是糟糕的设计。这个字段 不能 代替正确的 静态文件 处理。

### `BooleanField`

class `BooleanField`(**options)

一个 true／false 字段。

该字段的默认表单部件是 `CheckboxInput`，或者如果 `null=True` 则是 `NullBooleanSelect`。

当 `Field.default` 没有定义时，`BooleanField` 的默认值是 `None`。

### `CharField`

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

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

对于大量的文本，使用 `TextField`。

该字段的默认表单部件是一个 `TextInput`。

`CharField` 有两个额外的参数：

`CharField.``max_length`

  必须的。该字段的最大长度（以字符为单位）。max_length 在数据库层面强制执行，在 Django 的验证中使用 `MaxLengthValidator`。

  注解

  如果你编写的应用程序必须可移植到多个数据库后端，你应该意识到，有些后端对 `max_length` 有限制。详情请参考 数据库后端注释。

`CharField.``db_collation`
  New in Django 3.2.

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

  注解

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

  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()` 时，该字段才会自动更新。当以其他方式对其他字段进行更新时，如 `QuerySet.update()`，该字段不会被更新，尽管你可以在这样的更新中为该字段指定一个自定义值。

`DateField.``auto_now_add`

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

  - 对于 `DateField`: `default=date.today` ——来自 `datetime.date.today()`
  - 对于 `DateTimeField`: `default=timezone.now` ——来自 `django.utils.timezone.now()`

该字段的默认表单部件是一个 `DateInput`。管理中增加了一个 JavaScript 日历，以及“今天”的快捷方式。包含一个额外的 `invalid_date` 错误信息键。

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

注解

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

注解

`auto_now` 和 `auto_now_add` 选项将始终使用创建或更新时 默认时区 的日期。如果你需要一些不同的东西，你可能需要考虑使用你自己的可调用的默认值，或者覆盖 `save()` 而不是使用 `auto_now` 或 `auto_now_add` ；或者使用 `DateTimeField` 而不是 `DateField`，并决定如何在显示时间处理从日期时间到日期的转换。

### `DateTimeField`

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

一个日期和时间，在 Python 中用一个 `datetime.datetime` 实例表示。与 `DateField` 一样，使用相同的额外参数。

该字段的默认表单部件是一个单独的 `DateTimeInput`。管理中使用两个单独的 `TextInput` 部件，并使用 JavaScript 快捷方式。

### `DecimalField`

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

一个固定精度的十进制数，在 Python 中用一个 `Decimal` 实例来表示。它使用 `DecimalValidator` 验证输入。

有两个 必要的 参数：

`DecimalField.``max_digits`

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

`DecimalField.``decimal_places`

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

例如，如果要存储精度为小数点后两位的 `999` 的数字，你可以使用：

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

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

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

当 `localize` 为 `False` 时是 `NumberInput` 否则，该字段的默认表单部件是 `TextInput`。

注解

关于 `FloatField` 和 `DecimalField` 类之间差异的更多信息，请参见 FloatField vs. DecimalField。你还应该注意小数字段的 SQLite 限制。

### `DurationField`

class `DurationField`(**options)

一个用于存储时间段的字段——在 Python 中用 `timedelta` 建模。当在 PostgreSQL 上使用时，使用的数据类型是 `interval`，在 Oracle 上使用的数据类型是 `INTERVAL DAY(9) TO SECOND(6)`。否则使用微秒的 `bigint`。

注解

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

### `EmailField`

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

一个 `CharField`，使用 `EmailValidator` 来检查该值是否为有效的电子邮件地址。

### `FileField`

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

一个文件上传字段

注解

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

有两个可选参数：

`FileField.``upload_to`

  这个属性提供了一种设置上传目录和文件名的方式，可以有两种设置方式。在这两种情况下，值都会传递给 `Storage.save()` 方法。

  如果你指定一个字符串值或一个 `Path`，它可能包含 `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`，这个字符串的值将被附加到你的 `MEDIA_ROOT` 路径后面，形成本地文件系统中上传文件的存储位置。如果你使用的是不同的存储系统，请检查该存储系统的文档，看看它是如何处理 `upload_to` 的。

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

  参数 | 描述
  --- | ---
  `instance` | 定义 `FileField` 的模型实例。更具体地说，这是附加当前文件的特定实例。 在大多数情况下，这个对象还没有被保存到数据库，所以如果它使用默认的 `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`

  一个存储对象，或是一个返回存储对象的可调用对象。它处理你的文件的存储和检索。参见 管理文件，了解如何提供这个对象。

  Changed in Django 3.1:

  增加了提供可调用对象的能力。

该字段的默认表单部件是一个 `ClearableFileInput`。

在模型中使用 `FileField` 或 `ImageField` （见下文）需要几个步骤：

1. 在你的配置文件中，你需要定义 `MEDIA_ROOT` 作为你希望 Django 存储上传文件的目录的完整路径。（为了保证性能，这些文件不存储在数据库中。）定义 `MEDIA_URL` 作为该目录的基本公共 URL。确保这个目录是 Web 服务器的用户账号可以写的。
2. 将 `FileField` 或 `ImageField` 添加到你的模型中，定义 `upload_to` 选项，指定 `MEDIA_ROOT` 的子目录，用于上传文件。
3. 所有这些将被存储在你的数据库中的是一个文件的路径（相对于 `MEDIA_ROOT` ）。你很可能要使用 Django 提供的方便的 `url` 属性。例如，如果你的 `ImageField` 叫做 `mug_shot`，你可以在模板中使用 `{{ object.mug_shot.url }}` 获取图片的绝对路径。

例如，你的 `MEDIA_ROOT` 设置为 `'/home/media'`， `upload_to` 设置为 `'photos/%Y/%m/%d'`。`upload_to` 中的 `'%Y/%m/%d'` 部分是 `strftime()` 格式化，`'%Y'` 是四位数的年，`'%m'` 是两位数的月，`'%d'` 是两位数的日。如果你在 2007 年 1 月 15 日上传了一个文件，它将被保存在 `/home/media/photos/2007/01/15` 目录下。

如果你想检索上传文件的盘上文件名，或者文件的大小，可以分别使用 `name` 和 `size` 属性；关于可用属性和方法的更多信息，请参见 `File` 类参考和 管理文件 主题指南。

注解

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

上传的文件的相对 URL 可以通过 `url` 属性获得。内部调用底层 `Storage` 类的 `store()` 方法。

需要注意的是，无论何时处理上传的文件，你都应该密切关注你上传的文件在哪里，是什么类型的文件，以避免安全漏洞。对所有上传的文件进行验证，这样你才能确定文件是你认为的那样。例如，如果你盲目地让别人上传文件，不经过验证，就上传文件到你的 Web 服务器的文档根目录下，那么有人就可以上传一个 CGI 或 PHP 脚本，并通过访问它的 URL 在你的网站上执行该脚本。不要允许这种情况发生。

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

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

#### `FileField` 和 `FieldFile`

class `FieldFile`

当你访问一个模型上的 `FileField` 时，你会得到一个 `FieldFile` 的实例作为访问底层文件的代理。

`FieldFile` 的 API 与 `File` 的 API 相同，但有一个关键的区别。该类所封装的对象不一定是 Python 内置文件对象的封装 相反，它是 `Storage.open()` 方法结果的封装，该方法可能是 `File` 对象，也可能是自定义存储对 `File` API 的实现。

除了从 `File` 继承的 API，如 `read()` 和 `write()` 之外，`FieldFile` 还包括一些可以用来与底层文件交互的方法：

警告

该类的两个方法 `save()` 和 `delete()`，默认为将与相关 `FieldFile` 的模型对象保存在数据库中。

`FieldFile.``name`

文件名，包括从关联的 `Storage` 的根部开始的相对路径 `FileField`。

`FieldFile.``path`

一个只读属性，通过调用底层的 `path()` 方法，访问文件的本地文件系统路径。

`FieldFile.``size`

底层 `Storage.size()` 方法的结果。

`FieldFile.``url`

一个只读属性，通过调用底层 `Storage` 类的 `Storage()` 方法来访问文件的相对 URL。

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

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

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

`FieldFile.``close`()

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

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

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

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

注意 `content` 参数应该是 `django.core.files.File` 的实例，而不是 Python 内置的文件对象。你可以从现有的 Python 文件对象构造一个 `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")

更多信息，请参见 管理文件。

`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`，其选择仅限于文件系统中某个目录下的文件名。有一些特殊的参数，其中第一个参数是 必须的。

`FilePathField.``path`

  必须的。一个目录的绝对文件系统路径，这个 `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` 将用于过滤文件名。请注意，正则表达式将被应用于基本文件名，而不是完整的路径。例如：`"foo.*.txt$"`，它将匹配名为 `foo23.txt` 的文件，但不匹配 `bar.txt` 或 `foo23.png`。

`FilePathField.``recursive`

  可选。`True` 或 `False`。默认为 `False`。指定是否包含 `path` 的所有子目录。

`FilePathField.``allow_files`

  可选。 `True` 或 `False`。 默认值是 `True`。 指定是否应该包含指定位置的文件。 这个或 `allow_folders` 必须是 `True`。

`FilePathField.``allow_folders`

  可选。 `True` 或 `False`。 默认为 `False`。 指定是否应该包含指定位置的文件夹。 这个或 `allow_files` 必须是 `True`。

一个潜在的问题是 `match` 适用于基本文件名，而不是完整的路径。所以，这个例子：

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

...将匹配 `/home/images/foo.png`，但不匹配 `/home/images/foo/bar.png`，因为 `match` 适用于基本文件名（ `foo.png` 和 `bar.png` ）。

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

### `FloatField`

class `FloatField`(**options)

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

当 `localize` 为 `False` 时是 `NumberInput` 否则，该字段的默认表单部件是 `TextInput`。

`FloatField` vs. `DecimalField`

`FloatField` 类有时会与 `DecimalField` 类混淆。虽然它们都表示实数，但它们表示的方式不同。`FloatField` 内部使用 Python 的 `float` 类型，而 `DecimalField` 则使用 Python 的 `Decimal` 类型。关于两者之间的区别，请参见 Python 的 `decimal` 模块的文档。

### `ImageField`

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

继承 `FileField` 的所有属性和方法，但也验证上传的对象是有效的图像。

除了 `FileField` 的特殊属性外， `ImageField` 也有 `height` 和 `width` 属性。

为了方便查询这些属性，`ImageField` 有两个额外的可选参数。

`ImageField.``height_field`

  模型字段的名称，每次保存模型实例时将自动填充图像的高度。

`ImageField.``width_field`

  模型字段的名称，每次保存模型实例时将自动填充图像的宽度。

需要 Pillow 库。

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

该字段的默认表单部件是一个 `ClearableFileInput`。

### `IntegerField`

class `IntegerField`(**options)

一个整数。从 `-2147483648` 到 `2147483647` 的值在 Django 支持的所有数据库中都是安全的。

它使用 `MinValueValidator` 和 `MaxValueValidator` 根据默认数据库支持的值来验证输入。

当 `localize` 为 `False` 时是 `NumberInput` 否则，该字段的默认表单部件是 `TextInput`。

### `GenericIPAddressField`

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

IPv4 或 IPv6 地址，字符串格式（如 `192.0.2.30` 或 `2a02:42fe::4` ）。该字段的默认表单部件是一个 `TextInput`。

IPv6 地址规范化遵循 RFC 4291#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。

### `JSONField`

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

New in Django 3.1.

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

`JSONField` 在 MariaDB 10.2.7+、MySQL 5.7.8+、Oracle、PostgreSQL 和 SQLite（在 JSON1 扩展被启用的情况下）都支持。

`JSONField.``encoder`

  一个可选的 `json.JSONEncoder` 子类，用于序列化标准 JSON 序列化器不支持的数据类型（例如 `datetime.datetime` 或 `UUID` ）。例如，你可以使用 `DjangoJSONEncoder` 类。

  默认为 `json.JSONEncoder`。

`JSONField.``decoder`

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

  默认为 `json.JSONDecoder`。

如果你给字段一个 `default`，确保它是一个不可变的对象，比如 `str`，或者是一个每次返回一个新的可变对象的可调用对象，比如 `dict` 或一个函数。提供一个像 `default={}` 或 `default=[]` 这样的可改变的默认对象，在所有模型实例之间共享一个对象。

要在数据库中查询 `JSONField`，请看 查询 JSONField。

索引

`Index` 和 `Field.db_index` 都创建了一个 B 树索引，在查询 `JSONField` 的时候并不是特别有用。仅在 PostgreSQL 上，可以使用 `GinIndex` 比较适合。

PostgreSQL 用户

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

Oracle 用户

Oracle 数据库不支持存储 JSON 标量值。只支持 JSON 对象和数组（在 Python 中使用 `dict` 和 `list` 表示)。

### `NullBooleanField`

class `NullBooleanField`(**options)

就像 `BooleanField` 的 `null=True`。

3.1 版后已移除: `NullBooleanField` 已被废弃，改为 `BooleanField(null=True)`。

### `PositiveBigIntegerField`

class `PositiveBigIntegerField`(**options)

New in Django 3.1.

就像一个 `PositiveIntegerField`，但只允许在某一特定点下的值（依赖于数据库）。`0` 到 `9223372036854775807` 的值在 Django 支持的所有数据库中都是安全的。

### `PositiveIntegerField`

class `PositiveIntegerField`(**options)

就像 `IntegerField` 一样，但必须是正值或零（ `0` ）。从 `0` 到 `2147483647` 的值在 Django 支持的所有数据库中都是安全的。出于向后兼容的原因，接受 `0` 的值。

### `PositiveSmallIntegerField`

class `PositiveSmallIntegerField`(**options)

就像一个 `PositiveIntegerField`，但只允许在某一特定（数据库依赖的）点下取值。`0` 到 `32767` 的值在 Django 支持的所有数据库中都是安全的。

### `SlugField`

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

Slug 是一个报纸术语。slug 是一个简短的标签，只包含字母、数字、下划线或连字符。它们一般用于 URL 中。

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

意味着将 `Field.db_index` 设置为 `True`。

基于其他值的值自动预填充一个 SlugField 通常是很有用的。 你可以在管理中使用 `prepopulated_fields` 来自动完成。

它使用 `validate_slug` 或 `validate_unicode_slug` 进行验证。

`SlugField.``allow_unicode`

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

### `SmallAutoField`

class `SmallAutoField`(**options)

就像一个 `AutoField`，但只允许值在一定（依赖于数据库）的限制下。`1` 到 `32767` 的值在 Django 支持的所有数据库中都是安全的。

### `SmallIntegerField`

class `SmallIntegerField`(**options)

就像一个 `IntegerField`，但只允许在某一特定（依赖于数据库的）点下取值。从 `-32768` 到 `32767` 的值在 Django 支持的所有数据库中都是安全的。

### `TextField`

class `TextField`(**options)

一个大的文本字段。该字段的默认表单部件是一个 `Textarea`。

如果你指定了 `max_length` 属性，它将反映在自动生成的表单字段的 `Textarea` 部件中。但是，它并没有在模型或数据库层面被强制执行。使用一个 `CharField` 来实现。

`TextField.``db_collation`
  New in Django 3.2.

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

  注解

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

  Oracle

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

### `TimeField`

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

一个时间，在 Python 中用 `datetime.time` 实例表示。接受与 `DateField` 相同的自动填充选项。

该字段默认的表单部件t是一个 `TimeInput`。管理中添加了一些 JavaScript 快捷方式。

### `URLField`

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

URL 的 `CharField`，由 `URLValidator` 验证。

该字段的默认表单部件是一个 `URLInput`。

像所有的 `CharField` 子类一样， `URLField` 接受可选的 `max_length` 参数。如果你没有指定 `max_length` 参数，则使用默认的 200。

### `UUIDField`

class `UUIDField`(**options)

一个用于存储通用唯一标识符的字段。使用 Python 的 `UUID` 类。当在 PostgreSQL 上使用时，它存储在一个 `uuid` 的数据类型中，否则存储在一个 `char(32)` 中。

通用唯一标识符是 `primary_key` 的 `AutoField` 的一个很好的替代方案。数据库不会为你生成 UUID，所以建议使用 `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 上查找

在 PostgreSQL 上使用 `iexact`、`contains`、`icontains`、`startswith`、`istartswith`、`endswith` 或 `iendswith` 在 PostgreSQL 上查找没有连字符的值是行不通的，因为 PostgreSQL 将它们存储在一个连字符的 uuid 数据类型中。

## 关系字段

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

### `ForeignKey`

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

一个多对一的关系。需要两个位置参数：模型相关的类和 `on_delete` 选项。

要创建一个递归关系——一个与自己有多对一关系的对象——使用 `models.ForeignKey('self', on_delete=models.CASCADE)`。

如果你需要在一个尚未定义的模型上创建关系，你可以使用模型的名称，而不是模型对象本身：

    from django.db import models

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

    class Manufacturer(models.Model):
        # ...
        pass

在 抽象模型 上以这种方式定义的关系在模型被子类化为具体模型时得到解析，与抽象模型的 `app_label` 不是相关的：

products/models.py

    from django.db import models

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

        class Meta:
            abstract = True

production/models.py

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

    class Manufacturer(models.Model):
        pass

    class Car(AbstractCar):
        pass

    # Car.manufacturer will point to `production.Manufacturer` here.

要引用定义在另一个应用程序中的模型，你可以明确地用完整的应用程序标签指定一个模型。例如，如果上面的 `Manufacturer` 模型是在另一个叫做 `production` 的应用程序中定义的，你需要使用：

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

这种被称为懒惰关系的引用，在解决两个应用程序之间的循环导入依赖关系时很有用。

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

#### 数据库表现

在幕后，Django 在字段名后附加 `"_id"` 来创建数据库列名。在上面的例子中，`Car` 模型的数据库表将有一个 `manufacturer_id` 列。（你可以通过指定 `db_column` 来显式地改变这一点）然而，你的代码应该永远不需要处理数据库列名，除非你编写自定义 SQL。你将总是处理你的模型对象的字段名。

#### 参数

`ForeignKey` 接受其他定义关系工作细节的参数。

`ForeignKey.``on_delete`

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

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

  `on_delete` 不会在数据库中创建 SQL 约束。支持数据库级联选项 可能会在以后实施。

`on_delete` 的可能值可以在 `django.db.models` 中找到。

- `CASCADE`

    级联删除。Django 模拟了 SQL 约束 ON DELETE CASCADE 的行为，也删除了包含 ForeignKey 的对象。

    `Model.delete()` 在相关的模型上没有被调用，但是 `pre_delete` 和 `post_delete` 信号是为所有被删除的对象发送的。

- `PROTECT`

    通过引发 `ProtectedError`，即 `django.db.IntegrityError` 的子类，防止删除被引用对象。

- `RESTRICT`
    New in Django 3.1.

    通过引发 `RestrictedError` （ `django.db.IntegrityError` 的一个子类）来防止删除被引用的对象。与 `PROTECT` 不同的是，如果被引用的对象也引用了一个在同一操作中被删除的不同对象，但通过 `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` 本身。例如：

        >>> 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` 为空；只有当 `null` 为 `True` 时，才有可能。

- `SET_DEFAULT`

    将 `ForeignKey` 设置为默认值，必须为 `ForeignKey` 设置一个默认值。

- `SET`()

    将 `ForeignKey` 设置为传递给 `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` 除非你手动添加一个 SQL `ON DELETE` 约束条件到数据库字段。

`ForeignKey.``limit_choices_to`

  当使用 `ModelForm` 或管理中渲染该字段时，设置该字段的可用选择限制（默认情况下，查询集中的所有对象都可以选择）。可以使用字典、 `Q` 对象，或者返回字典或 `Q` 对象的可调用对象。

  例子：

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

  导致 `ModelForm` 上的对应字段只列出有 `is_staff=True` 的 `Users`。这在 Django 管理中可能会有帮助。

  例如，当与 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对象`，这对 复杂的查询 很有用，那么只有当该字段没有在 `ModelAdmin` 中的 `raw_id_fields` 中列出时，它才会对管理中可用的选择产生影响。

  注解

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

`ForeignKey.``related_name`

  用于从相关对象到这个对象的关系的名称。这也是 `related_query_name` 的默认值（用于从目标模型反向过滤名称的名称）。请参阅 关联对象文档 以获得完整的解释和示例。请注意，当你在 抽象模型 是可用的。

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

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

`ForeignKey.``related_query_name`

  目标模型中反向过滤器的名称。如果设置了，它默认为 `related_name` 或 `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` 一样，`related_query_name` 通过 一些特殊的语法 支持应用标签和类的插值。

`ForeignKey.``to_field`

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

`ForeignKey.``db_constraint`

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

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

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

`ForeignKey.``swappable`

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

  只有当你确定你的模型应该始终指向交换的模型——例如，如果它是一个专门为你的自定义用户模型设计的配置文件模型，你才希望将此覆盖为 `False`。

  将它设置为 `False` 并不意味着你可以引用一个可交换的模型，即使它被交换了—— `False` 意味着用这个外键进行的迁移将始终引用你指定的确切模型（所以如果用户试图用你不支持的 User 模型运行，它将失败，例如）。

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

### `ManyToManyField`

class `ManyToManyField`(to, **options)

一个多对多的关系。需要一个位置参数：模型相关的类，它的工作原理与 `ForeignKey` 完全相同，包括 递归 和 惰性 关系。

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

#### 数据库表现

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

#### 参数

`ManyToManyField` 接受一组额外的参数——都是可选的——控制关系如何运作。

`ManyToManyField.``related_name`

  与 `ForeignKey.related_name` 相同。

`ManyToManyField.``related_query_name`

  与 `ForeignKey.related_query_name` 相同。

`ManyToManyField.``limit_choices_to`

  与 `ForeignKey.limit_choices_to` 相同。

  `limit_choices_to` 在使用 `through` 参数指定自定义中间表的 `ManyToManyField` 上使用时没有效果。

`ManyToManyField.``symmetrical`

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

      from django.db import models

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

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

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

`ManyToManyField.``through`

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

  这个选项最常见的用法是当你想把 额外的数据与多对多关系 联系起来。

  注解

  如果你不想让同一个实例之间有多个关联，可以添加一个 `UniqueConstraint`，包括 from 和 to 字段。Django 自动生成的多对多表就包含了这样的约束。

  注解

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

  如果你没有指定一个显式的 `through` 模型，你仍然可以使用一个隐式的 `through` 模型类来直接访问为保持关联而创建的表。它有三个字段来链接模型。

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

  - `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` 上的模型（本例中为 `group` ）的外键名称，`field2` 是目标模型（本例中为 `person` ）的外键名称。

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

`ManyToManyField.``db_table`

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

`ManyToManyField.``db_constraint`

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

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

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

`ManyToManyField.``swappable`

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

  只有当你确定你的模型应该始终指向交换的模型——例如，如果它是一个专门为你的自定义用户模型设计的配置文件模型，你才希望将此覆盖为 `False`。

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

`ManyToManyField` 不支持 `validators`。

`null` 没有效果，因为没有办法在数据库层面要求建立关系。

### `OneToOneField`

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

一对一的关系。概念上，这类似于 `ForeignKey` 与 `unique=True`，但关系的“反向”将直接返回一个单一对象。

最有用的是作为某种方式“扩展”另一个模型的主键；多表继承 是通过添加一个从子模型到父模型的隐式一对一关系来实现的，例如：

需要一个位置参数：模型将与之相关的类。这与 `ForeignKey` 的工作原理完全相同，包括关于 递归 和 惰性 关系的所有选项。

如果没有为 `OneToOneField` 指定 `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` 模型将有以下属性：

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

当访问反向关系时，如果相关表中的条目不存在，就会引发一个 `RelatedObjectDoesNotExist` 异常。这是目标模型的 `Model.DoesNotExist` 异常的一个子类。例如，如果一个用户没有一个由 `MySpecialUser` 指定的主管：

    >>> user.supervisor_of
    Traceback (most recent call last):
        ...
    RelatedObjectDoesNotExist: User has no supervisor_of.

此外，`OneToOneField` 接受 `ForeignKey` 接受的所有额外参数，外加一个额外参数：

`OneToOneField.``parent_link`

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

参见 一对一关系，了解 `OneToOneField` 的使用实例。

## 字段 API 参考

class `Field`

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

  因此，一个字段在不同的 Django API 中是一个基本的部分，特别是 `models` 和 `querysets`。

  在模型中中，字段被实例化为一个类属性，并代表一个特定的表列，见 模型。它的属性有 `null` 和 `unique`，以及 Django 用来将字段值映射到数据库特定值的方法。

  `Field` 是 `RegisterLookupMixin` 的子类，因此 `Transform` 和 `Lookup` 都可以在它上面注册，以便在 `QuerySet` 中使用（例如： `field_name__exact="foo"` ）。所有 内置查找 都是默认注册的。

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

  `description`

    字段的详细描述，例如： `django.contrib.admindocs` 应用程序。

    描述的形式可以是：

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

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

  `descriptor_class`

    一个实现 描述符协议 的类，它被实例化并分配给模型实例属性。构造函数必须接受一个参数，即 `Field` 实例。覆盖该类属性可以自定义获取和设置行为。

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

  `get_internal_type`()

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

    参见 仿造内置字段类型 在自定义字段中的用法。

  `db_type`(connection)

    返回 `Field` 的数据库列数据类型，并考虑 `connection`。

    参见 自定义数据库类型 在自定义字段中的用法。

  `rel_db_type`(connection)

    返回指向 `Field` 的 `ForeignKey` 和 `OneToOneField` 等字段的数据库列数据类型，并考虑 `connection`。

    参见 自定义数据库类型 在自定义字段中的用法。

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

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

  查询时，使用 `get_db_prep_value()` 和 `get_prep_value()`。

  `get_prep_value`(value)

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

    见 将 Python 转为查询值 的用法。

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

    将 `value` 转换为后台特定的值，默认情况下，如果 `prepared=True`，则返回 `value`。默认情况下，如果 `prepared=True`，它将返回 `value`，而如果是 `False`，它将返回 `get_prep_value()` 。

    使用方法参见 将查询值转为数据库值。

  加载数据时，使用 `from_db_value()`。

  `from_db_value`(value, expression, connection)

    将数据库返回的值转换为 Python 对象。与 `get_prep_value()` 相反。

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

    `expression` 与 `self` 相同。

    使用方法参见 将值转为 Python 对象。

    注解

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

  保存时，使用 `pre_save()` 和 `get_db_prep_save()` ：

  `get_db_prep_save`(value, connection)

    与 `get_db_prep_value()` 相同，但当字段值必须 保存 到数据库中时，会被调用。默认情况下返回 `get_db_prep_value()`。

  `pre_save`(model_instance, add)

    在 `get_db_prep_save()` 之前调用的方法，在保存前准备好值（例如 `DateField.auto_now` ）。

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

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

    使用方法参见 在保存前预处理数值。

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

  `to_python`(value)

    将值转换为正确的 Python 对象。它的作用与 `value_to_string()` 相反，并且在 `clean()` 中也被调用。

    使用方法参见 将值转为 Python 对象。

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

  `value_from_object`(obj)

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

    这个方法经常被 `value_to_string()` 使用。

  `value_to_string`(obj)

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

    使用方法参见 为序列化转换字段数据。

  当使用 `model forms` 时，`Field` 需要知道它应该由哪个表单字段来表示。

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

    返回该字段默认的 `django.forms.Field` 给 `ModelForm`。

    默认情况下，如果 `form_class` 和 `choices_form_class` 都是 `None`，则使用 `CharField`。如果字段有 `chips`，且 `choices_form_class` 没有指定，则使用 `TypedChoiceField`。

    使用方法参见 为模型字段指定表单字段。

  `deconstruct`()

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

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

    这个方法必须添加到 1.7 之前的字段中，才能使用 迁移 迁移其数据。

# 字段属性参考

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

## 字段的属性

`Field.``auto_created`

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

`Field.``concrete`

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

`Field.``hidden`

  布尔值标志，表示一个字段是否用于支持另一个非隐藏字段的功能（例如，组成 `GenericForeignKey` 的 `content_type` 和 `object_id` 字段）。`hidden` 标志用于区分构成模型上公共字段子集的内容和模型上所有字段。

  注解

  `Options.get_fields()` 默认情况下不包括隐藏字段。传入 `include_hidden=True` 在结果中返回隐藏字段。

`Field.``is_relation`

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

`Field.``model`

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

## 有关系的字段的属性

这些属性用于查询关系的基数和其他细节。这些属性在所有字段上都存在；但是，如果字段是关系类型（ `Field.is_relation=True` ），它们只有布尔值（而不是 `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`。