Django 2.1.3 模型层 字段类型

未完待续…

本文档包含所有Field的API参考,包括Django提供的 字段选项 和 字段类型。

也可以看看
如果内置字段不起作用,您可以尝试使用django-localflavor文档),其中包含对特定国家和文化有用的各种代码片段。
此外,您可以轻松编写自己的 自定义模型字段。↑

注意
从技术上讲,这些模型是在django.db.models.fields中定义的,但为方便起见,它们被导入到django.db.models; 标准惯例是使用 from django.db import models和引用字段 models.XXXField。

1.字段选项

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

null

Field.null

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

避免在基于字符串的字段上使用null,例如 CharField和TextField。如果基于字符串的字段具有 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,则需要该字段。

choices

Field.choices

可迭代的(例如,列表或元组),其由恰好两个项目(例如[(A, B), (A, B) ...])的可迭代对象组成,以用作该字段的选择。如果给出了choice,则通过模型验证强制执行,默认表单部件将是具有这些选项而不是标准文本字段的选择框。
每个元组中的第一个元素是要在模型上设置的实际值,第二个元素是人类可读的名称。例如:

YEAR_IN_SCHOOL_CHOICES = (
    ('FR', 'Freshman'),
    ('SO', 'Sophomore'),
    ('JR', 'Junior'),
    ('SR', 'Senior'),
)

通常,最好在模型类中定义choices,并为每个值定义适当命名的常量:

from django.db import models

class Student(models.Model):
    FRESHMAN = 'FR'
    SOPHOMORE = 'SO'
    JUNIOR = 'JR'
    SENIOR = 'SR'
    YEAR_IN_SCHOOL_CHOICES = (
        (FRESHMAN, 'Freshman'),
        (SOPHOMORE, 'Sophomore'),
        (JUNIOR, 'Junior'),
        (SENIOR, 'Senior'),
    )
    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'),
)

每个元组中的第一个元素是要应用于组的名称。第二个元素是一个可迭代的2元组,每个2元组包含一个值和一个人类可读的选项名称。分组选项可以与单个列表中的未分组选项组合(例如本示例中的unknown)。

译者注:此种用法的效果如下,粗体是不可选的。
在这里插入图片描述
对于已设置choices的每个模型字段,Django将添加一个方法来检索字段当前值的可读名称。请参阅 get_FOO_display() 数据库API文档。

>>> from filter.models import NoBody
>>> p = NoBody.objects.get(id=1)
>>> p.get_media_display()
'Vinyl'
>>>

请注意,choice可以是任何可迭代对象 - 不一定是列表或元组。这使您可以动态构造选择。但是,如果你发现自己 choices变得动态,你可能最好使用一个合适的数据库表ForeignKey。如果有可能的话,choices用于静态数据,变化不大的数据。

除非在字段上设置blank=False, 否则将使用选择框呈现default为"---------"(如上面的图)。要覆盖此行为,请将一个包含None的元组添加到choices中 ; 例如(None, 'Your String For Display')。或者在CharField,您可以使用空字符串替代None,这样看起来更有意义 。

效果图:
在这里插入图片描述

db_column

Field.db_column

用于此字段的数据库列的名称。如果没有给出,Django将使用该字段的名称。

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

db_index

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

db_tablespace

Field.db_tablespace

如果此字段已建立索引,则用于此字段表示索引的数据库表空间名称。默认值为项目的 DEFAULT_INDEX_TABLESPACE设置。如果后端不支持索引的表空间,则忽略此选项。

default

Field.default

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

默认不能是可变对象(模型实例,list,set等),作为该对象的相同实例的引用将被用作在所有新的模型实例的默认值。应该将所需的默认值包装在可调用的函数中。例如,如果要为JSONField指定一个默认的dict ,使用函数:

def contact_default():
    return {"email": "[email protected]"}
contact_info = JSONField("ContactInfo", default=contact_default)

匿名函数lambdas不能用于字段选项的default,因为它们无法通过 迁移进行序列化。请参阅其他警告的文档。

对于ForeignKey映射到模型实例的字段,default值应该是它们引用的字段的值(除非已设置 to_field,否则就是pk)而不是模型实例。

创建新模型实例并且未为该字段提供值时,将使用默认值。当字段是主键时,默认值也会在字段设置为None时使用。

editable

Field.editable

默认是True。如果为False,该字段将不会显示在admin或任何其他ModelForm中 。在模型验证期间也会跳过它们。
在这里插入图片描述

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将自动添加一个AutoField来保存主键,因此除非要覆盖默认的主键行为,否则不需要设置任何字段为primary_key=True。有关更多信息,请参阅 自动主键字段

primary_key=True实现了null=False和 unique=True。对象上只允许一个主键。

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

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_for_date和unique_for_month。

verbose_name

Field.verbose_name

该字段的人类可读名称。如果没有给出详细名称,Django将使用字段的属性名称自动创建它,将下划线转换为空格。请参见verbose备注名称
在这里插入图片描述

validators

Field.validators

要为此字段运行的验证程序列表。有关更多信息,请参阅验证器文档

注册和获取查找

Field实现查找注册API。API可用于自定义类中哪些字段可用于查找,以及如何从字段中提取并查找。

2.字段类型

AutoField

class AutoField(**options)

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

BigAutoField

class BigAutoField(**options)

一个64位整数,很像一个AutoField,不同之处在于它是保证数字从1到9223372036854775807

BigIntegerField

classBigIntegerField(** options)
一个64位整数,很像一个IntegerField不同之处在于它是保证数字从-9223372036854775808 到 9223372036854775807。此字段的默认表单部件是TextInput

BinaryField

class BinaryField(max_length=None, **options)
用于存储原始二进制数据的字段。它可以分配 bytes, bytearray或memoryview。

默认情况下,BinaryField设置editable为False,在这种情况下,它不能包含在ModelForm中。

在Django 2.1中更改:
较旧的版本不允许设置editable为True,新版可以。
在这里插入图片描述
BinaryField 有一个额外的可选参数:

BinaryField.max_length
字段的最大长度(以字符为单位)。在Django的验证中使用MaxLengthValidator强制执行最大长度 。

滥用 BinaryField
虽然您可能会考虑将文件存储在数据库中,但请考虑在99%的情况下这是不好的设计。此字段不要来做静态文件处理。

BooleanField

class BooleanField(**options)
一个真/假字段。

此字段的默认表单部件是CheckboxInput,或者NullBooleanSelect(需要null=True)。

默认值BooleanField是None,当Field.default 没有定义的时候。
在这里插入图片描述
在Django 2.1中更改
在旧版本中,此字段不允许null=True,因此您必须使用NullBooleanField。现在不鼓励使用后者,因为它可能会在Django的未来版本中被弃用。

CharField

class CharField(max_length=None, **options)
字符串字段,用于从小到大的字符串。

对于大量文本,请使用TextField

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

CharField 有一个额外的必要参数:

CharField.max_length
字段的最大长度(以字符为单位)。max_length在数据库级别和Django的验证中使用 MaxLengthValidator 强制执行 。

注意
如果您正在编写一个必须可移植到多个数据库后端的应用程序,您应该知道在某些后端max_length存在限制 。有关详细信息,请参阅 数据库后端说明。↑

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- from datetime.date.today()
  • 对于DateTimeField:default=timezone.now- from django.utils.timezone.now()

此字段的默认表单部件是TextInput。管理员添加了一个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决定如何在显示时处理从datetime到date的转换。↑

DateTimeField

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

日期和时间,由Python的datetime.datetime实例表示。采用和DateField相同的额外参数。

此字段的默认表单部件是单个 TextInput。管理员使用两个单独的 TextInput部件和JavaScript快捷方式。

DecimalField

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

一个固定精度的十进制数,由Python的 Decimal实例表示。它使用DecimalValidator验证输入 。

有两个必需的参数

DecimalField.max_digits
数字中允许的最大位数(不包含小数点)。请注意,此数字必须大于或等于decimal_places。

DecimalField.decimal_places
与数字一起存储的小数位数。

例如,要存储999,精度为2位小数的数字,您可以使用:

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

存储大约10亿的数字,精度为10位小数:

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

此字段的默认表单控件是NumberInput 或者TextInput(需要设置localize=False)。
在这里插入图片描述
注意
有关FloatField和DecimalField类之间差异的更多信息 ,请参阅FloatField与DecimalField

DurationField

class DurationField(**options)

用于存储时间段的字段 - 用Python中的timedelta。在PostgreSQL上使用时,使用的数据类型是interval,在Oracle上使用时,数据类型是INTERVAL DAY(9) TO SECOND(6);其它使用bigint微秒。

译者注:我这里使用的是Mysql
在这里插入图片描述
注意
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,如果使用则会引发错误。↑

有两个可选参数:

upload_to

此属性提供了设置上传目录和文件名的方法,可以通过两种方式进行设置。在这两种情况下,都将值传递给 Storage.save()方法。

如果指定字符串值,则可能包含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)

storage

存储对象,用于处理文件的存储和检索。有关如何提供此对象的详细信息,请参阅管理文件

此字段的默认表单部件是 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''%Y'是四位数的年份,'%m'是两位数的月份,'%d'是两位数的一天。如果您在2007年1月15日上传文件,它将保存在目录/home/media/photos/2007/01/15中。

如果要检索上传文件的磁盘文件名或文件大小,可以分别使用name和 size属性; 有关可用属性和方法的更多信息,请参阅 File 类引用和管理文件 主题指南。

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

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

请注意,无论何时处理上传的文件,都应密切关注上传文件的位置以及文件类型,以避免安全漏洞。验证所有上传的文件,以确保文件符合您的认可。例如,如果您盲目地让某人上传文件而不进行验证,则将文件上传到Web服务器文档根目录中的目录,然后有人可以上传CGI或PHP脚本并通过访问您网站上的URL来执行该脚本。不要允许。(译者注:可以使用编辑器的上传功能,这样会减少不安全文件的漏洞,例如,KindEditor)

另请注意,即使是上传的HTML文件,因为它可以由浏览器执行(虽然不是由服务器执行),但可能会造成相当于XSS或CSRF攻击的安全威胁。

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

FileField和FieldFile

class FieldFile
当您访问模型的FileField时,您将获得一个FieldFile实例用于访问基础文件的代理实例。

FieldFile的API 是File的镜像,有一个关键区别:由类包装的对象不一定是Python的内置文件对象的包装器。相反,它是Storage.open() 方法结果的包装器,可以是File对象,也可以是自定义存储的File API 实现。

除了从File继承了API 诸如 read()和write(),FieldFile包括可用于与下面的文件交互的几种方法:

警告
这个类中,有两种方法save()和delete(),默认保存和FieldFile模型相关的对象在数据库中。

FieldFile.name

Storage根路径的与FileField关联的相对路径的文件名 。

FieldFile.size

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

FieldFile.url

一个只读属性,用于通过调用基础Storage类的url()方法来访问文件的相对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=None, match=None, recursive=False, max_length=100, **options)
一个CharField,仅限于文件系统上某个目录中的文件名。有三个特殊参数,其中第一个是必需的:

FilePathField.path
需要。一个目录的绝对文件系统路径,FilePathField从中可以选择它。示例:"/home/images"

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 。

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

FloatField

class FloatField(**options)

由在Python中的float实例表示的浮点数。

此字段的默认表单控件是NumberInput 或 TextInput(需要设置当localize=False)。

FloatField 与 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实例在数据库中创建为默认最大长度为100个字符的varchar 列。与其他字段一样,您可以使用max_length参数更改最大长度。

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

IntegerField

class IntegerField(**options)
整数。从-2147483648到2147483647,在Django支持的所有数据库中都是安全的。

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

此字段的默认表单控件是NumberInput 或 TextInput(需要设置当localize=False)。

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’时使用。

如果允许留空(blank=True),则必须允许空值(NULL),因为空值存储为NULL。

NullBooleanField

class NullBooleanField(**options)
就像BooleanField用null=True。使用BooleanField代替此字段,因为它可能在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。

实现了db_index=True

根据某些其他值的值自动预填充SlugField通常很有用。您可以在管理员中自动执行此操作 prepopulated_fields

它用validate_slugvalidate_unicode_slug来进行验证。

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

SmallIntegerField

class SmallIntegerField(**options)

像一个IntegerField,但只允许在某个(数据库相关的)范围下的值。从-32768到32767,在Django支持的所有数据库中安全。

TextField

class TextField(**options)

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

如果指定max_length属性,它将影响自动生成的表单Textarea字段部件。但是,它不会在模型或数据库级别强制执行。使用一个 CharField。

TimeField

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

一个时间,由Python 中 datetime.time实例表示。同DateField,接受相同的自动填充选项。

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

URLField

class URLField(max_length=200, **options)

一个CharField,应用于URL,经过URLValidator验证 。

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

与所有CharField子类一样,URLField采用可选 max_length参数。如果未指定 max_length,则使用默认值200

UUIDField

class URLField(max_length=200, **options)

用于存储唯一通用标识符的字段。使用Python的 UUID类。在PostgreSQL上使用时,它以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的实例。

3.关系字段

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

3.1 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,否则您的代码永远不必处理数据库列名。您将始终处理模型对象的字段名称。

3.1.1 参数

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

ForeignKey.on_delete

当删除被 ForeignKey 引用的对象时,Django将根据on_delete参数指定的SQL约束有进一步行动 。例如,如果您有一个可为空的ForeignKey,并且希望在删除引用的对象时将其设置为null:

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_deletepost_delete信号。

  • PROTECT
    通过引发ProtectedError( django.db.IntegrityError的子类)来防止删除引用的对象。

  • SET_NULL
    设置 ForeignKey 为null; 只有null=True,才能这么设置。

  • SET_DEFAULT
    将ForeignKey设置为默认值; ForeignKey必须设置的default 。

  • 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或admin 呈现此字段时,为此字段的可用选项设置限制(默认情况下,可以选择查询集中的所有对象)。可以是一个字典,一个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.utcnow()}

limit_choices_to = limit_pub_date_choices

如果limit_choices_to是Q对象或返回Q对象,这对复杂的查询很有帮助。在后台,它影响使用ModelAdmin并且不显示没有列在raw_id_fields中的字段。

注意
如果使用了可调用的 limit_choices_to,则每次实例化新表单时都会调用它。也可以在验证模型时调用它,例如通过管理命令或管理员。admin构造查询集以多次验证其在各种边缘情况下的表单输入,因此可能会多次调用您的可调用对象。↑

ForeignKey.related_name

用于从相关对象返回到此关系的关系的名称。它也是related_query_name(用于目标模型的反向过滤器名称的名称)的默认值。有关完整说明和示例,请参阅反向查询文档 。请注意,在抽象模型上定义关系时必须设置此值 ; 当你这样做时,可以使用 一些特殊的语法

如果你想让Django不创建反向关系,设置 related_name到'+'或以'+'结束。例如,这将确保User模型与此模型不具有向后关系:

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

译者实例
原来需要p.book_set.all()才能查出与之关联的所有书籍,现在通过p.books.all()就可以查出,而且book_set不能再使用。
在这里插入图片描述

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通过一些 些特殊的语法 支持app标签和类插值。

译者实例
(1)定义模型

class Book(models.Model):
	#...省略
    publish = models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE,
                                related_name='books',
                                related_query_name='booking')

(2)查询

p = Publish.objects.filter(booking__title__contains='呐').first()
b = p.books.all()
print(b)
# 输出结果
<QuerySet [<Book: 呐喊>, <Book: 灭亡>]>

ForeignKey.to_field

关系所涉及的相关对象上的字段。默认情况下,Django使用相关对象的主键。如果您引用其他字段,则该字段必须具有unique=True,实例如上。

ForeignKey.db_constraint

控制是否应在数据库中为此外键创建约束。默认是True,这几乎可以肯定你想要的; 将此设置False为非常糟糕的数据完整性。也就是说,这里有一些你可能想要这样做的场景:

  • 您的遗留数据无效。
  • 您正在分片数据库。

如果设置为False,则访问不存在的相关对象将引发其DoesNotExist异常。

ForeignKey.swappable

如果ForeignKey 指向可交换模型,则控制迁移框架的反应。如果是True- 默认值 - 那么如果ForeignKey指向与当前settings.AUTH_USER_MODEL的值(或其他可交换模型设置)匹配的模型,则关系将存储在迁移中(通过一个一个引用指向setting),而不是直接存储在模型中。

如果您确定模型应始终指向交换模型,则只需要覆盖此项为False- 例如,如果它是您的自定义用户模型设计的模型(翻译有点问题,原文for example, if it is a profile model designed specifically for your custom user model )。

将其设置为False并不意味着您可以引用可交换模型,即使它已被换出 - False只是意味着使用此ForeignKey进行的迁移将始终引用您指定的确切模型(例如,如果用户尝试使用您不支持的用户模型)。

如有疑问,请将其保留为默认值True。

3.2 ManyToManyField

class ManyToManyField(to, **options)

多对多的关系。需要一个位置参数:与模型相关的类,这个参数与 ForeignKey中的作用完全相同,包括递归和 惰性关系。

可以使用字段的RelatedManager添加,删除或创建相关对象 。

数据库表示
在幕后,Django创建了一个中间连接表来表示多对多关系。默认情况下,此表名称是使用多对多字段的名称以及包含它的模型的表名生成的。由于某些数据库不支持超过一定长度的表名,因此这些表名将自动截断为64个字符,并将使用唯一性哈希。这意味着您可能会看到表名称 author_books_9cdf4; 这是完全正常的。您可以使用db_table选项手动提供连接表的名称。

3.2.1 参数

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

仅用于自定义ManyToManyFields。考虑以下模型:

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模型。

此选项最常见的用途是,您希望将 额外数据与多对多关系相关联

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

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

  • id:关系的主键。
  • <containing_model>_id:声明 ManyToManyField的模型的id 。
  • <other_model>_id:ManyToManyField指向的模型的id 。

如果ManyToManyField来自并指向同一模型,则生成以下字段:

  • id:关系的主键。
  • from_<model>id:id指向模型的实例(即源实例)。
    *to<model>_id:id关系指向的实例(即目标模型实例)。
    此类可用于查询给定模型实例的关联记录,如普通模型。

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(personinviter),这使得关系模糊不清,Django无法知道使用哪一个。在这种情况下,您必须使用through_fields明确指定Django应使用哪些外键,如上例所示。

through_fields接受一个2元组('field1', 'field2'),其中 field1和field2都是外键的名称。

如果中间模型上有多个外键到参与多对多关系的任何(甚至所有)模型,则必须指定through_fields。这也适用于 使用中间模型且模型有两个以上外键的递归关系,或者您想要明确指定Django应使用哪两个。

使用中间模型的递归关系总是被定义为非对称的 - 也就是说symmetrical=False 因此,存在“源”和“目标”的概念。在这种情况下,'field1'将被视为关系的“源”, 'field2'为“目标”。

ManyToManyField.db_table

要创建用于存储多对多数据的表的名称。如果没有提供,Django将根据以下名称假定一个默认名称:定义关系的模型表和字段本身的名称。
在这里插入图片描述

ManyToManyField.db_constraint

控制是否应在数据库中为中间表中的外键创建约束。默认是True,这几乎可以肯定你想要的; 将此设置False为非常糟糕的数据完整性。也就是说,这里有一些你可能想要这样做的场景:

  • 您的遗留数据无效。
    ( 您正在分片数据库。

同时提供db_constraint和through会报错

ManyToManyField.swappable

ForeignKey.swappable

ManyToManyField不支持validators。

null 没有效果,因为无法在数据库级别要求关系。

3.3 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

访问反向关系时,如果在相关表中的条目不存在报出DoesNotExist异常。例如,如果MySpecialUser没有指定supervisor :

>>> user.supervisor_of
Traceback (most recent call last):
    ...
DoesNotExist: User matching query does not exist.

3.3.1 参数

另外,OneToOneField接受所有和ForeignKey一样的参数,加上一个额外的参数:

OneToOneField.parent_link

继承自另一个 具体模型 的模型中使用True时,表示该字段应该用作返回父类的链接,而不是通常由子类隐式创建的额外OneToOneField字段 。

有关使用示例,请参阅一对一关系实例

猜你喜欢

转载自blog.csdn.net/lengfengyuyu/article/details/84932830