模型字段引用

本文档包含 Field 包括 field optionsfield types Django提供。

参见

如果内置字段不起作用,您可以尝试 django-localflavor (documentation 其中包含对特定国家和文化有用的各种代码片段。

而且,你可以很容易地 write your own custom model fields .

备注

从技术上讲,这些模型在 django.db.models.fields 但为了方便起见,它们被进口到 django.db.models 标准惯例是使用 from django.db import models 并将字段引用为 models.<Foo>Field .

字段选项

以下参数可用于所有字段类型。所有都是可选的。

null

Field.null

如果 True ,django将空值存储为 NULL 在数据库中。默认是 False .

避免使用 null 基于字符串的字段,如 CharFieldTextField . 如果基于字符串的字段 null=True ,这意味着它有两个可能的“无数据”值: NULL 和空字符串。在大多数情况下,“无数据”有两个可能的值是多余的;django约定使用空字符串,而不是 NULL . 一个例外是 CharField 都有 unique=Trueblank=True 集合。在这种情况下, null=True 在保存多个值为空的对象时,需要避免唯一的约束冲突。

对于基于字符串和非基于字符串的字段,还需要设置 blank=True 如果您希望允许表单中的空值, null 参数只影响数据库存储(请参见 blank

备注

使用Oracle数据库后端时,该值 NULL 将存储以表示空字符串,而不考虑此属性。

blank

Field.blank

如果 True ,该字段允许为空。默认是 False .

注意这与 null . null 纯粹与数据库相关,而 blank 是否与验证相关。如果字段有 blank=True ,表单验证将允许输入空值。如果字段有 blank=False ,字段将是必需的。

提供缺少的值

blank=True 可以与具有以下属性的字段一起使用 null=False ,但这将需要实施 clean() 以便以编程方式提供任何缺少的值。

choices

Field.choices[源代码]

下面描述的格式的映射或可迭代,用作此字段的选项。如果给出了选择,这些选择是由 model validation 默认的表单小部件将是包含这些选项的选择框,而不是标准文本字段。

如果给出了映射,则关键元素是要在模型上设置的实际值,第二个元素是人类可读的名称。例如::

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

您还可以传递一个 sequence 由恰好包含两个项的可迭代项组成(例如 [(A1, B1), (A2, B2), …] )。每个元组中的第一个元素是要在模型上设置的实际值,第二个元素是人类可读的名称。例如::

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

choices 也可以定义为不需要任何参数并返回上述任何格式的Callable。例如::

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 例如,在以下情况下可以特别方便:

  • 受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" 选项)。

您还可以使用序列,例如二元组列表:

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

注意,选择可以是任何序列对象——不一定是列表或元组。这允许您动态地构造选项。但如果你发现自己被黑客攻击 choices 为了保持动态,最好使用适当的数据库表 ForeignKey . choices 用于静态数据,如果有变化的话,不会太大。

备注

每次按 choices 变化。

对于具有以下属性的每个模型字段 choices 设置后,Django将把选择标准化为一个二元组列表,并添加一个方法来检索字段当前值的人类可读名称。看见 get_FOO_display() 在数据库API文档中。

除非 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,
        default=YearInSchool.FRESHMAN,
    )

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

这些工作类似于 enum 来自Python的标准库,但进行了一些修改:

  • 枚举成员值是构造具体数据类型时使用的参数元组。Django支持在此元组的末尾添加额外的字符串值以用作人类可读的名称,或者 label 。这个 label 可以是懒惰的可翻译字符串。因此,在大多数情况下,成员值将是 (value, label) 2-元组。有关详情,请参阅以下内容 an example of subclassing choices 使用更复杂的数据类型。如果未提供元组,或者最后一项不是(惰性)字符串,则 labelautomatically generated 从成员名称。

  • A .label 属性添加到值上,以返回人类可读的名称。

  • 许多定制属性被添加到枚举类中-- .choices.labels.values ,以及 .names --使访问枚举的这些单独部分的列表变得更容易。

    警告

    这些属性名称不能用作成员名称,因为它们会发生冲突。

  • 对.的使用 enum.unique() 强制执行是为了确保值不能被多次定义。在选择领域时不太可能预料到这一点。

请注意,使用 YearInSchool.SENIORYearInSchool['SENIOR'] ,或 YearInSchool('SR') 要访问或查找enum成员按预期工作, .name.value 成员的财产。

如果您不需要翻译人类可读的名称,您可以从成员名称推断它们(用空格替换下划线并使用标题大小写):

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

由于enum值需要为integer的情况非常常见,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 需要注意的是,标签是按照上面突出显示的方式自动生成的:

>>> 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')]

如果您需要对除以下具体数据类型的支持 intstr ,你可以进行子类 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)"

还有一些额外的注意事项需要注意:

  • 列举类型不支持 named groups

  • 由于具有具体数据类型的列举需要所有值与该类型匹配,因此重写 blank label 无法通过创建具有值的成员来实现 None .相反,设置 __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 **

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_defaultField.default 都设置好了, default 在使用Python代码创建实例时将优先使用。 db_default 仍将在数据库级别设置,并将在ORM之外插入行或在迁移中添加新字段时使用。

db_index

Field.db_index

如果 True ,将为此字段创建数据库索引。

使用 indexes 而不是选择。

如果可能,请使用 Meta.indexes 选项取而代之。在几乎所有的情况下, indexes 提供的功能比 db_indexdb_index 在将来可能会被弃用。

db_tablespace

Field.db_tablespace[源代码]

的名字 database tablespace 用于该字段的索引(如果该字段已编入索引)。默认值是项目的 DEFAULT_INDEX_TABLESPACE 设置,如果设置,或 db_tablespace 如果有的话。如果后端不支持索引的表空间,则忽略此选项。

default

Field.default

字段的默认值。这可以是一个值或可调用对象。如果可调用,则每次创建新对象时都会调用它。

默认值不能是可变对象(模型实例, listset 等),因为对该对象同一实例的引用将被用作所有新模型实例中的默认值。相反,将所需的默认值包装在可调用中。例如,如果您想指定默认值 dictJSONField ,使用函数::

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


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

lambda 不能用于字段选项,如 default 因为他们不能 serialized by migrations . 有关其他注意事项,请参阅该文档。

对于像 ForeignKey 映射到模型实例的默认值应该是它们引用的字段的值。 (pk 除非 to_field 而不是模型实例。

创建新模型实例时使用默认值,但没有为字段提供值。当字段是主键时,当字段设置为 None .

也可以使用在数据库级别设置缺省值 Field.db_default

editable

Field.editable

如果 False ,该字段将不会显示在管理员或任何其他 ModelForm . 在 model validation . 默认是 True .

error_messages

Field.error_messages[源代码]

这个 error_messages 参数允许您重写字段将引发的默认消息。传入一个字典,其中的键与要重写的错误消息匹配。

错误消息键包括 nullblankinvalidinvalid_choiceuniqueunique_for_date . 为中的每个字段指定了其他错误消息键。 Field types 下面部分。

这些错误消息通常不会传播到表单。见 关于模型的考虑 error_messages .

help_text

Field.help_text

要与表单小部件一起显示的额外“帮助”文本。它对文档很有用,即使表单上没有使用您的字段。

注意这个值是 not HTML以自动生成的表单转义。这允许您在 help_text 如果你愿意的话。例如::

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=Falseunique=True . 一个对象上只允许有一个主键。

主键字段是只读的。如果更改现有对象的主键值,然后保存它,则将在旧对象旁边创建一个新对象。

主键字段设置为 None 什么时候 deleting 一件物品。

unique

Field.unique[源代码]

如果 True ,此字段在整个表中必须是唯一的。

这是在数据库级别和通过模型验证强制执行的。如果试图将具有重复值的模型保存到 unique A域 django.db.IntegrityError 将由模型的 save() 方法。

此选项对除 ManyToManyFieldOneToOneField .

注意什么时候 uniqueTrue ,您不需要指定 db_index ,因为 unique 意味着创建索引。

unique_for_date

Field.unique_for_date

将此设置为 DateFieldDateTimeField 要求此字段对于日期字段的值是唯一的。

例如,如果您有字段 title 那有 unique_for_date="pub_date" ,那么django就不允许输入两个相同的记录 titlepub_date .

请注意,如果将此设置为指向 DateTimeField 只考虑字段的日期部分。此外,什么时候 USE_TZTrue ,将在 current time zone 在保存对象时。

这是强制执行 Model.validate_unique() 在模型验证期间,但不是在数据库级别。如果有的话 unique_for_date 约束涉及不属于 ModelForm (例如,如果其中一个字段列在 exclude 或有 editable=FalseModel.validate_unique() 将跳过该特定约束的验证。

unique_for_month

Field.unique_for_month

喜欢 unique_for_date ,但要求字段相对于月份是唯一的。

unique_for_year

Field.unique_for_year

喜欢 unique_for_dateunique_for_month .

verbose_name

Field.verbose_name

字段的可读名称。如果没有给出详细名称,Django将使用字段的属性名自动创建该名称,并将下划线转换为空格。见 Verbose field names .

validators

Field.validators[源代码]

要为此字段运行的验证程序列表。见 validators documentation 更多信息。

字段类型

AutoField

class AutoField(**options)[源代码]

IntegerField 根据可用的ID自动递增。您通常不需要直接使用它;如果您不另外指定,主键字段将自动添加到您的模型中。见 自动主键字段 .

BigAutoField

class BigAutoField(**options)[源代码]

64位整数,很像 AutoField 但它保证符合 19223372036854775807 .

BigIntegerField

class BigIntegerField(**options)[源代码]

一个64位的整数,很像一个 IntegerField 除了保证适合来自 -92233720368547758089223372036854775807 .此字段的默认表单小部件是 NumberInput

BinaryField

class BinaryField(max_length=None, **options)[源代码]

存储原始二进制数据的字段。它可以被分配 bytesbytearraymemoryview .

默认情况下, BinaryField 集合 editableFalse ,在这种情况下,它不能包含在 ModelForm .

BinaryField.max_length

可选的。字段的最大长度(以字节为单位)。最大长度在Django的验证中使用 MaxLengthValidator

滥用 BinaryField

尽管您可能会考虑在数据库中存储文件,但在99%的情况下,考虑到这是一个糟糕的设计。这个字段是 not 适当的替代品 static files 处理。

BooleanField

class BooleanField(**options)[源代码]

真/假字段。

此字段的默认表单小部件是 CheckboxInputNullBooleanSelect 如果 null=True .

默认值为 BooleanFieldNone 什么时候? Field.default 未定义。

CharField

class CharField(max_length=None, **options)[源代码]

字符串字段,用于小到大的字符串。

对于大量文本,请使用 TextField .

此字段的默认表单小部件是 TextInput .

CharField 有以下额外的参数:

CharField.max_length

字段的最大长度(以字符为单位)。这个 max_length 在数据库级别和Django的验证中使用 MaxLengthValidator 。Django附带的所有数据库后端都需要它,但PostgreSQL除外,它支持无限制 VARCHAR 柱子。

备注

如果编写的应用程序必须可移植到多个数据库后端,则应注意对 max_length 对于一些后端。参考 database backend notes 有关详细信息。

CharField.db_collation

可选的.字段的数据库排序规则名称。

备注

整理名称不标准化。因此,这将无法跨多个数据库后台移植。

甲骨文公司

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

此字段的默认表单小部件是 DateInput .管理员添加了JavaScript日历和“Today”的快捷方式。包括附加 invalid_date 错误消息键。

选项 auto_now_addauto_nowdefault 相互排斥。这些选项的任何组合都将导致错误。

备注

如当前实施,设置 auto_nowauto_now_addTrue 会导致现场 editable=Falseblank=True 集合。

备注

这个 auto_nowauto_now_add 选项将始终使用 default timezone 在创建或更新时。如果您需要不同的东西,您可能需要考虑使用自己的可调用默认值或重写 save() 与其使用 auto_nowauto_now_add ;或使用 DateTimeField 而不是一个 DateField 并决定如何处理从日期时间到显示时间的日期的转换。

警告

始终使用 DateField 使用一个 datetime.date 举个例子。

如果你有一个 datetime.datetime 例如,建议将其转换为 datetime.date 先如果你不这样做, DateField 将本地化 datetime.datetime 发送到 default timezone 并将其转换为 datetime.date 例如,删除其时间分量。对于存储和比较来说都是如此。

DateTimeField

class DateTimeField(auto_now=False, auto_now_add=False, **options)[源代码]

日期和时间,用python表示 datetime.datetime 实例。采用与 DateField .

此字段的默认表单小部件是一个 DateTimeInput .管理员使用两个独立的 TextInput 具有JavaScript快捷方式的小部件。

警告

始终使用 DateTimeField 使用一个 datetime.datetime 举个例子。

如果你有一个 datetime.date 例如,建议将其转换为 datetime.datetime 先如果你不这样做, DateTimeField 将在午夜使用 default timezone 对于时间部分。对于存储和比较来说都是如此。比较的日期部分 DateTimeField 使用一个 datetime.date 例如,使用 date 查一查。

DecimalField

class DecimalField(max_digits=None, decimal_places=None, **options)[源代码]

一个固定精度的十进制数,在python中用 Decimal 实例。它使用验证输入 DecimalValidator .

具有以下特性 required 论据:

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)

此字段的默认表单小部件是 NumberInput 什么时候? localizeFalseTextInput 否则。

备注

有关之间差异的更多信息 FloatFieldDecimalField 班级,请看 FloatField vs. DecimalField .您还应该了解 SQLite limitations 小数字段。

DurationField

class DurationField(**options)[源代码]

用于存储时间段的字段-用python建模 timedelta . 在PostgreSQL上使用时,使用的数据类型是 interval 在Oracle上,数据类型是 INTERVAL DAY(9) TO SECOND(6) . 否则,A bigint 使用微秒。

备注

算术与 DurationField 在大多数情况下都有效。但是,在PostgreSQL以外的所有数据库上,比较 DurationField 运算 DateTimeField 实例将无法按预期工作。

EmailField

class EmailField(max_length=254, **options)[源代码]

A CharField 检查该值是否为有效的电子邮件地址,使用 EmailValidator .

FileField

class FileField(upload_to='', storage=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

存储对象,或返回存储对象的可调用对象。它处理文件的存储和检索。看到 文档管理 了解有关如何提供此对象的详细信息。

此字段的默认表单小部件是 ClearableFileInput .

使用A FileFieldImageField (见下文)在一个模型中,采取了几个步骤:

  1. 在您的设置文件中,您需要定义 MEDIA_ROOT 作为您希望Django存储上传文件的目录的完整路径。(出于性能考虑,这些文件不存储在数据库中。)定义 MEDIA_URL 作为该目录的基本公共URL。确保Web服务器的用户帐户可以写入此目录。

  2. 添加 FileFieldImageField 对于您的模型,定义 upload_to 指定子目录的选项 MEDIA_ROOT 用于上载的文件。

  3. 数据库中存储的所有内容都是指向文件的路径(相对于 MEDIA_ROOT )你很可能想利用方便 url Django提供的属性。例如,如果 ImageField 被称为 mug_shot ,可以获取模板中图像的绝对路径 {{{{ object.mug_shot.url }}}} .

例如,说 MEDIA_ROOT 设置为 '/home/media'upload_to 设置为 'photos/%Y/%m/%d' . 这个 '%Y/%m/%d' 部分 upload_tostrftime() 格式化; '%Y' 是四位数的年份, '%m' 是两位数的月份和 '%d' 是两位数的一天。如果您在2007年1月15日上传一个文件,它将保存在目录中。 /home/media/photos/2007/01/15 .

如果要检索上载文件的磁盘文件名或文件大小,可以使用 namesize 属性;有关可用属性和方法的详细信息,请参见 File 类引用和 文档管理 主题指南。

备注

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

上载文件的相对URL可以使用 url 属性。在内部,这调用 url() 底层的方法 Storage 类。

请注意,无论何时处理上传的文件,都应该密切关注上传位置以及上传的文件类型,以避免安全漏洞。 Validate all uploaded files 这样你就能确定这些文件就是你想的那样。例如,如果您盲目地允许某人在未经验证的情况下将文件上传到您的Web服务器的文档根目录中,则某人可以上传CGI或PHP脚本,并通过访问其在您网站上的URL来执行该脚本。不允许这样做。

另外请注意,即使是上载的HTML文件,由于它可以由浏览器执行(而不是由服务器执行),也可能造成等同于XSS或CSRF攻击的安全威胁。

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

FileField and FieldFile

class FieldFile[源代码]

当您访问 FileField 在模型上,您将获得 FieldFile 作为访问基础文件的代理。

API FieldFile 镜子的 File ,有一个关键区别: The object wrapped by the class is not necessarily a wrapper around Python's built-in file object. 相反,它是围绕 Storage.open() 方法,可以是 File 对象,或者它可以是自定义存储的 File 应用程序编程接口。

除了继承自 Fileread()write()FieldFile 包括可用于与基础文件交互的几种方法:

警告

这门课有两种方法, save()delete() ,默认为保存关联的模型对象 FieldFile 在数据库中。

FieldFile.name

文件名,包括根目录下的相对路径 Storage 相关联的 FileField .

FieldFile.path[源代码]

一个只读属性,通过调用 path() 底层方法 Storage 班级。

FieldFile.size[源代码]

基础的结果 Storage.size() 方法。

FieldFile.url[源代码]

只读属性,通过调用 url() 底层的方法 Storage 类。

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的内置文件对象。你可以构造一个 File 来自现有的python文件对象,如下所示:

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)[源代码]

A CharField 其选择仅限于文件系统上某个目录中的文件名。有一些特殊的论点,其中第一个是 required

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 将用于筛选文件名。请注意,regex将应用于基文件名,而不是完整路径。例子: "foo.*\.txt$" ,它将与名为 foo23.txt 但不是 bar.txtfoo23.png .

FilePathField.recursive

可选的。要么 TrueFalse . 默认是 False . 指定是否所有子目录 path 应该包括在内

FilePathField.allow_files

可选的。要么 TrueFalse True . 指定是否应包括指定位置的文件。要么是这个,要么是 allow_folders 必须是 True .

FilePathField.allow_folders

可选的。要么 TrueFalse False . 指定是否应包括指定位置的文件夹。要么是这个,要么是 allow_files 必须是 True .

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

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

……将匹配 /home/images/foo.png 但不是 /home/images/foo/bar.png 因为 match 应用于基本文件名 (foo.pngbar.png

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

FloatField

class FloatField(**options)[源代码]

在python中由 float 实例。

此字段的默认表单小部件是 NumberInput 什么时候? localizeFalseTextInput 否则。

FloatField vs. DecimalField

这个 FloatField 有时课程和 DecimalField 类。虽然它们都代表实数,但它们代表的数字不同。 FloatField 使用Python的 float 在内部键入,而 DecimalField 使用Python的 Decimal 类型。有关这两者之间的区别的信息,请参见 decimal 模块。

GeneratedField

class GeneratedField(expression, output_field, db_persist=None, **kwargs)[源代码]

始终根据模型中的其他字段计算的字段。此字段由数据库本身管理和更新。使用 GENERATED ALWAYS SQL语法。

生成的列有两种:存储列和虚拟列。存储生成的列是在写入(插入或更新)时计算的,并占用存储空间,就像它是常规列一样。虚拟生成的列不占用存储空间,在读取时进行计算。因此,虚拟生成的列类似于视图,而存储的生成的列类似于实例化视图。

GeneratedField.expression

一个 Expression 由数据库用来在每次更改模型时自动设置字段值。

表达式应该是确定性的,并且仅引用模型内的字段(在同一数据库表中)。生成的字段不能引用其他生成的字段。数据库后端可以施加进一步的限制。

GeneratedField.output_field

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

GeneratedField.db_persist

确定数据库列是否应像实际列一样占用存储空间。如果 False ,该列充当虚拟列,不占用数据库存储空间。

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

刷新数据

由于数据库始终计算值,因此必须重新加载对象才能在 save() ,例如,通过使用 refresh_from_db()

数据库限制

对于生成的字段,有许多特定于数据库的限制,Django不会对其进行验证,并且数据库可能会引发错误,例如,PostgreSQL要求将生成的列中引用的函数和运算符标记为 IMMUTABLE

你应该经常检查一下 expression 在您的数据库上支持。检查 MariaDBMySQLOraclePostgreSQL ,或 SQLite 医生。

GenericIPAddressField

class GenericIPAddressField(protocol='both', unpack_ipv4=False, **options)[源代码]

字符串格式的IPv4或IPv6地址(例如 192.0.2.302a02:42fe::4 )此字段的默认表单小部件是 TextInput .

IPv6地址规范化如下 RFC 4291#section-2.2 第2.2节,包括使用该节第3段中建议的IPv4格式,如 ::ffff:192.0.2.0 . 例如, 2001:0::0:01 将规范化为 2001::1::ffff:0a0a:0a0a::ffff:10.10.10.10 . 所有字符都转换为小写。

GenericIPAddressField.protocol

将有效输入限制为指定的协议。接受值为 'both' (默认) 'IPv4''IPv6' . 匹配不区分大小写。

GenericIPAddressField.unpack_ipv4

解包IPv4映射地址,如 ::ffff:192.0.2.1 . 如果启用此选项,地址将解包到 192.0.2.1 . 默认设置为禁用。只能在以下情况下使用 protocol 设置为 'both' .

如果允许空值,则必须允许空值,因为空值存储为空。

ImageField

class ImageField(upload_to=None, height_field=None, width_field=None, max_length=100, **options)[源代码]

从继承所有属性和方法 FileField ,但也验证上载的对象是有效的图像。

除了可用于 FileField ,一个 ImageField 也有 heightwidth 属性。

为了便于对这些属性的查询, ImageField 具有以下可选参数:

ImageField.height_field

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

ImageField.width_field

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

需要 Pillow 类库。

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

此字段的默认表单小部件是 ClearableFileInput .

IntegerField

class IntegerField(**options)[源代码]

整数。值从 -21474836482147483647 在Django支持的所有数据库中都是安全的。

它使用 MinValueValidatorMaxValueValidator 根据默认数据库支持的值验证输入。

此字段的默认表单小部件是 NumberInput 什么时候? localizeFalseTextInput 否则。

JSONField

class JSONField(encoder=None, decoder=None, **options)[源代码]

用于存储JSON编码数据的字段。在python中,数据以其python本机格式表示:字典、列表、字符串、数字、布尔值和 None .

JSONField 在MariaDB、MySQL、Oracle、PostgreSQL和SQLite(具有 JSON1 extension enabled )。

JSONField.encoder

可选的 json.JSONEncoder 用于序列化标准SON序列化器不支持的数据类型的子类别(例如 datetime.datetimeUUID ).例如,您可以使用 DjangoJSONEncoder 班级。

默认为 json.JSONEncoder

JSONField.decoder

可选的 json.JSONDecoder 用于对从数据库检索的值进行反序列化的子类。该值将采用自定义编码器选择的格式(最常见的是字符串)。您的反序列化可能需要考虑您无法确定输入类型的事实。例如,您面临退回的风险 datetime 这实际上是一个字符串,其格式恰好与 datetime S。

默认为 json.JSONDecoder

查询 JSONField 在数据库中,请参阅 正在查询 JSONField

缺省值

如果您为该字段指定一个 default ,确保它是可调用的,如 dict 类或每次都返回一个新对象的函数。错误地使用像这样的可变对象 default={}default=[] 创建在所有实例之间共享的可变默认设置。

索引

IndexField.db_index 两者都创建B树索引,这在查询时不是特别有帮助 JSONField .仅在PostgreSQL上,您可以使用 GinIndex 那更适合。

PostgreSQL用户

PostgreSQL有两种基于本地JSON的数据类型: jsonjsonb . 它们之间的主要区别在于如何存储它们以及如何查询它们。波斯特雷克尔 json 字段存储为JSON的原始字符串表示形式,并且在根据键进行查询时必须动态解码。这个 jsonb 字段是基于允许索引的JSON的实际结构存储的。权衡是一个很小的额外成本,写给 jsonb 字段。 JSONField 使用 jsonb .

Oracle用户

Oracle数据库不支持存储SON纯量值。仅限SON对象和数组(在Python中使用 dictlist )被支持。

PositiveBigIntegerField

class PositiveBigIntegerField(**options)[源代码]

像一个 PositiveIntegerField ,但仅允许某个(依赖于数据库)点下的值。值从 09223372036854775807 在Django支持的所有数据库中都安全。

PositiveIntegerField

class PositiveIntegerField(**options)[源代码]

像一个 IntegerField ,但必须为正或零 (0 )值从 02147483647 在Django支持的所有数据库中都是安全的。价值 0 因为向后兼容的原因而被接受。

PositiveSmallIntegerField

class PositiveSmallIntegerField(**options)[源代码]

像一个 PositiveIntegerField ,但只允许在特定(依赖于数据库)点下的值。值从 032767 在Django支持的所有数据库中都是安全的。

SlugField

class SlugField(max_length=50, **options)[源代码]

Slug 是报纸术语。slug是某个事物的简短标签,仅包含字母、数字、下划线或连字符。它们通常用于URL中。

像charfield一样,您可以指定 max_length (阅读有关数据库可移植性和 max_length 在那一部分也是如此)。如果 max_length 未指定,Django将使用默认长度50。

暗示设置 Field.db_indexTrue .

根据其他值的值自动预填充SlugField通常很有用。您可以在管理员中使用 prepopulated_fields .

它使用 validate_slugvalidate_unicode_slug 用于验证。

SlugField.allow_unicode

如果 True 字段除接受ASCII字母外还接受Unicode字母。默认为 False .

SmallAutoField

class SmallAutoField(**options)[源代码]

像一个 AutoField ,但仅允许某个(取决于数据库)限制下的值。值从 132767 在Django支持的所有数据库中都安全。

SmallIntegerField

class SmallIntegerField(**options)[源代码]

像一个 IntegerField ,但只允许在特定(依赖于数据库)点下的值。值从 -3276832767 在Django支持的所有数据库中都是安全的。

TextField

class TextField(**options)[源代码]

大文本字段。此字段的默认表单小部件是 Textarea .

max_length 属性,它将反映在 Textarea 自动生成表单字段的小部件。但是,它不是在模型或数据库级别强制执行的。使用A CharField 为此。

TextField.db_collation

可选的.字段的数据库排序规则名称。

备注

整理名称不标准化。因此,这将无法跨多个数据库后台移植。

甲骨文公司

Oracle不支持 TextField

TimeField

class TimeField(auto_now=False, auto_now_add=False, **options)[源代码]

用python表示的时间 datetime.time 实例。接受与相同的自动填充选项 DateField .

此字段的默认表单小部件是 TimeInput .管理员添加了一些JavaScript快捷方式。

URLField

class URLField(max_length=200, **options)[源代码]

A CharField 对于URL,由验证 URLValidator .

此字段的默认表单小部件是 URLInput

像所有 CharField 子类, URLField 选择 max_length 参数。如果您不指定 max_length ,默认值为200。

UUIDField

class UUIDField(**options)[源代码]

用于存储通用唯一标识符的字段。使用Python的 UUID 班级。在PostgreSQL和MariaDB 10.7+上使用时,它存储在 uuid 数据类型,否则在 char(32)

通用唯一标识符是 AutoField 对于 primary_key . 数据库不会为您生成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和MariaDB 10.7+上进行查找

vbl.使用 iexactcontainsicontainsstartswithistartswithendswith ,或 iendswith 对于没有连字符的值,在PostgreSQL上的查找不起作用,因为PostgreSQL和MariaDB 10.7+将它们存储在用连字符连接的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

以这种方式定义的关系 abstract models 当模型被子类化为具体模型并且与抽象模型的 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_indexFalse . 如果要创建一个用于一致性而不是联接的外键,或者要创建一个可选索引(如部分索引或多列索引),则可能需要避免索引的开销。

数据库表示

幕后,Django Appends "_id" 以创建其数据库列名。在上面的示例中, Car 模型将有一个 manufacturer_id 列。(您可以通过指定 db_column )但是,除非编写自定义SQL,否则代码不应该处理数据库列名。您将始终处理模型对象的字段名。

参数

ForeignKey 接受定义关系如何工作的详细信息的其他参数。

ForeignKey.on_delete

当一个对象被 ForeignKey 如果删除,Django将模拟由 on_delete 参数。例如,如果您有一个可以为空的 ForeignKey 您希望在删除引用的对象时将其设置为空::

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

on_delete 不会在数据库中创建SQL约束。支持数据库级级联选项 may be implemented later

的可能值 on_delete 发现于 django.db.models

  • CASCADE[源代码]

    级联删除。Django模拟删除层叠时SQL约束的行为,并删除包含foreignkey的对象。

    Model.delete() 没有调用相关模型,但 pre_deletepost_delete 为所有删除的对象发送信号。

  • PROTECT[源代码]

    通过引发阻止删除引用的对象 ProtectedError 一个子类 django.db.IntegrityError .

  • RESTRICT[源代码]

    通过引发防止删除引用对象 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 可以删除,即使这意味着删除 Album 它由一个 Song ,因为 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 空;只有在 nullTrue .

  • SET_DEFAULT[源代码]

    设置 ForeignKey 默认值;默认值 ForeignKey

  • SET()[源代码]

    设置 ForeignKey 设置为传递到的值 SET() ,或者如果传入了Callable,则为调用它的结果。在大多数情况下,传递可调用对象是必要的,以避免在执行 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 只列出 Users 那有 is_staff=True . 这可能对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 object ,这对 complex queries ,则只有当字段未在中列出时,它才会对管理员中可用的选项产生影响。 raw_id_fieldsModelAdmin 对于模型。

备注

如果可调用文件用于 limit_choices_to ,它将在每次实例化新窗体时调用。它也可以在验证模型时调用,例如通过管理命令或管理。管理员构造查询集以在各种边缘情况下多次验证其表单输入,因此可能会多次调用您的可调用项。

ForeignKey.related_name

用于从相关对象返回到此对象的关系的名称。它也是默认值 related_query_name (用于目标模型中的反向筛选器名称的名称)。见 related objects documentation 为了一个完整的解释和例子。请注意,在定义关系时必须设置此值 abstract models ;当你这样做的时候 some special syntax 可用。

如果您希望Django不创建反向关系,请设置 related_name'+' 或者结束它 '+' . 例如,这将确保 User 模型与此模型没有向后关系:

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

用于目标模型中的反向筛选器名称的名称。默认值为 related_namedefault_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_namerelated_query_name 通过支持应用程序标签和类插值 some special syntax .

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 意味着使用此ForeignKey进行的迁移将始终引用您指定的确切模型(因此,例如,如果用户尝试使用您不支持的用户模型运行,则会严重失败)。

如有疑问,将其视为违约 True .

ManyToManyField

class ManyToManyField(to, **options)[源代码]

一种多对多的关系。需要位置参数:与模型相关的类,它的工作方式与它的工作方式完全相同 ForeignKey 包括 recursivelazy 关系。

相关对象可以使用字段的 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 .

ManyToManyField.symmetrical

仅用于定义“自我上的许多场”。考虑以下模型:

from django.db import models


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

当Django处理此模型时,它标识它具有 ManyToManyField 因此,它不会添加 person_set 属性 Person 类。相反, ManyToManyField 假设是对称的——也就是说,如果我是你的朋友,那么你就是我的朋友。

如果你不想在多对多关系中对称 self ,集合 symmetricalFalse . 这将强制Django添加反向关系的描述符,允许 ManyToManyField 关系是非对称的。

ManyToManyField.through

Django将自动生成一个表来管理多对多关系。但是,如果要手动指定中间表,可以使用 through 用于指定表示要使用的中间表的django模型的选项。

此选项最常用的用法是当您要关联 extra data with a many-to-many relationship .

备注

如果您不希望同一实例之间存在多个关联,请添加 UniqueConstraint 包括从和到字段。Django自动生成的多对多表包含这样的约束。

备注

使用中间模型的回归关系无法确定反向访问器名称,因为它们是相同的。您需要设置 related_name 至少对其中一个人来说。如果您不希望Django创建向后关系,请设置 related_name'+'

如果不指定显式 through 模型,还有一个隐式的 through 可用于直接访问为保存关联而创建的表的模型类。它有三个字段来链接模型。

如果源模型和目标模型不同,将生成以下字段:

  • id :关系的主键。

  • <containing_model>_idid 声明的模型的 ManyToManyField .

  • <other_model>_idid 模型的 ManyToManyField 指向。

如果 ManyToManyField 从同一模型指向同一模型,将生成以下字段:

  • id :关系的主键。

  • from_<model>_idid 指向模型的实例(即源实例)。

  • to_<model>_idid 关系指向的实例(即目标模型实例)。

此类可用于查询给定模型实例(例如普通模型)的关联记录::

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)

Membershiptwo 外键 Person (personinviter ,这使得关系模糊不清,姜戈不知道该用哪一个。在这种情况下,必须使用 through_fields 如上例所示。

through_fields 接受2元组 ('field1', 'field2') 在哪里 field1 是模型的外键的名称 ManyToManyField 定义在 (group 在这种情况下),以及 field2 目标模型的外键的名称 (person 在这种情况下)。

当您在一个中介模型上有多个外键连接到参与多对多关系的模型中的任何一个(甚至两个)时,您 must 指定 through_fields . 这也适用于 recursive relationships 当使用中间模型并且模型有两个以上的外键时,或者您希望显式指定应该使用哪两个Django。

ManyToManyField.db_table

为存储多对多数据而创建的表的名称。如果没有提供,Django将根据定义关系的模型的表名和字段本身的名称,采用默认名称。

ManyToManyField.db_constraint

控制是否应在数据库中为中间表中的外键创建约束。默认值为 True ,这几乎是你想要的;设置为 False 可能对数据完整性非常不利。也就是说,下面是一些您可能希望这样做的场景:

  • 您的旧数据无效。

  • 您正在共享数据库。

两个都通过是错误的 db_constraintthrough .

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 包括所有关于 recursivelazy 关系。

如果不指定 related_name 的参数 OneToOneField ,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

A RelatedObjectDoesNotExist 如果相关表中的条目不存在,则在访问反向关系时引发异常。这是目标模型的子类 Model.DoesNotExist 异常,并且可以作为反向访问器的属性进行访问。例如,如果用户没有由指定的主管 MySpecialUser **

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

此外, OneToOneField 接受接受接受的所有额外参数 ForeignKey ,再加上一个参数:

什么时候? True 在继承自另一个模型的模型中使用 concrete model ,指示此字段应用作返回父类的链接,而不是用作 OneToOneField 通常是通过子类化隐式创建的。

One-to-one relationships 使用示例 OneToOneField .

现场API参考

class Field[源代码]

Field 是表示数据库表列的抽象类。Django使用字段创建数据库表 (db_type() )将python类型映射到数据库 (get_prep_value() )反之亦然 (from_db_value()

因此,字段是不同django API中的基本部分,特别是, modelsquerysets .

在模型中,字段被实例化为类属性并表示特定的表列,请参见 模型 . 它具有如下属性: nullunique 以及Django用于将字段值映射到数据库特定值的方法。

A Field 是的子类 RegisterLookupMixin 因此两者 TransformLookup 可以在上面注册以用于 QuerySet s(例如) field_name__exact="foo" )所有 built-in lookups 默认情况下注册。

所有Django的内置字段,例如 CharField ,是 Field . 如果需要自定义字段,可以将任何内置字段子类化,也可以编写 Field 白手起家。无论哪种情况,请参见 如何创建自定义模型字段 .

description

字段的详细描述,例如 django.contrib.admindocs 应用。

描述的形式可以是:

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

从字段的 __dict__ .

descriptor_class

实现 descriptor protocol 它被实例化并分配给模型实例属性。构造函数必须接受一个参数,即 Field instance.重写此类属性允许自定义获取和设置行为。

地图A Field 对于特定于数据库的类型,Django公开了几种方法:

get_internal_type()[源代码]

返回为后端特定目的命名此字段的字符串。默认情况下,它返回类名。

模拟内置字段类型 用于自定义字段。

db_type(connection)[源代码]

返回的数据库列数据类型 Field ,考虑到 connection .

自定义数据库类型 用于自定义字段。

rel_db_type(connection)[源代码]

返回字段的数据库列数据类型,如 ForeignKeyOneToOneField 指的是 Field ,考虑到 connection .

自定义数据库类型 用于自定义字段。

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

  • 查询数据库时(python value->database backend value)

  • 从数据库加载数据时(数据库后端值->python值)

  • 当它保存到数据库时(python value->database backend value)

查询时, get_db_prep_value()get_prep_value() 使用:

get_prep_value(value)[源代码]

value 是模型属性的当前值,该方法应返回已准备好用作查询参数的格式的数据。

将python对象转换为查询值 供使用。

get_db_prep_value(value, connection, prepared=False)[源代码]

皈依者 value 到后端特定的值。默认情况下,它返回 value 如果 prepared=Trueget_prep_value() 如果是 False .

将查询值转换为数据库值 供使用。

加载数据时, from_db_value() 使用:

from_db_value(value, expression, connection)

将数据库返回的值转换为python对象。它与 get_prep_value() .

此方法不用于大多数内置字段,因为数据库后端已经返回正确的python类型,或者后端本身进行转换。

expression 与之相同 self

将值转换为python对象 供使用。

备注

出于性能原因, from_db_value 不作为不需要它的字段(所有Django字段)的no-op实现。因此你不能调用 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 , the Field 需要知道它应该用哪个表单域表示:

formfield(form_class=None, choices_form_class=None, **kwargs)[源代码]

返回默认值 django.forms.Field 这个领域的 ModelForm .

默认情况下,如果两者都是 form_classchoices_form_classNone ,它使用 CharField . 如果现场有 choiceschoices_form_class 未指定,它使用 TypedChoiceField .

为模型字段指定窗体字段 供使用。

deconstruct()[源代码]

返回包含足够信息的4元组以重新创建字段:

  1. 模型上字段的名称。

  2. 字段的导入路径(例如 "django.db.models.IntegerField" )这应该是最便携的版本,所以越不具体越好。

  3. 位置参数列表。

  4. 关键字参数的字典。

必须将此方法添加到1.7之前的字段中,才能使用 迁徙 .

注册和获取查找

Field 实现 lookup registration API 。该API可用于定制可用于字段类及其实例的查找,以及如何从字段获取查找。

字段属性引用

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

字段的属性

Field.auto_created

指示是否自动创建字段的布尔标志,例如 OneToOneField 由模型继承使用。

Field.concrete

指示字段是否有关联的数据库列的布尔标志。

Field.hidden

布尔标志,指示字段是否隐藏并且不应由返回 Options.get_fields() 在默认情况下一个例子是 ForeignKey 使用一个 related_name 开头 '+'

Field.is_relation

布尔标志,指示字段是否包含对一个或多个其他模型的功能引用(例如 ForeignKeyManyToManyFieldOneToOneField 等)。

Field.model

返回定义字段的模型。如果在模型的超类上定义了字段, model 将引用超类,而不是实例的类。

具有关系的字段的属性

这些属性用于查询关系的基数和其他详细信息。这些属性存在于所有字段中;但是,它们只具有布尔值(而不是 None )如果字段是关系类型 (Field.is_relation=True

Field.many_to_many

布尔标志,即 True 如果字段有多对多关系; False 否则。Django中唯一包含的字段 TrueManyToManyField .

Field.many_to_one

布尔标志,即 True 如果字段有多对一关系,例如 ForeignKeyFalse 否则。

Field.one_to_many

布尔标志,即 True 如果字段有一对多关系,例如 GenericRelation 或者A的反面 ForeignKeyFalse 否则。

Field.one_to_one

布尔标志,即 True 如果字段有一对一关系,例如 OneToOneFieldFalse 否则。

Field.related_model

指向与字段相关的模型。例如, Author 在里面 ForeignKey(Author, on_delete=models.CASCADE) . 这个 related_model 对于一个 GenericForeignKey 总是 None .