Django Model层字段类型详解

字段选项

以下参数适用于所有字段类型。所有这些都是可选的。
null
Field.null
如果为True,Django将在数据库中存储空值NULL,默认是False。

需要注意的是空字符串值总是在数据库中存储为空字符串,而不是NULL。只有像整数、布尔和日期等非字符串字段才使用null=True。对于这两种类型,如果想为空值还需要设置blank=True。null 参数只影响数据库存储(查看blank)。

基于字符串的字段避免使用null,像 CharField 和 TextField  。如果基于字符串的字段null=True,这意味着他有两个可能的空值:NULL、空字符串。大多数情况下有两种“空值”是多余的,因为Django的惯例是使用空字符串而不是NULL。

如果你想使用BooleanField 字段接受NULL,可以使用NullBooleanField 代替。
blank
Field.blank

如果为True,则允许该字段为空白。默认是false。

请注意,这个是不同于null的。null纯粹是与数据库相关而blank与验证相关。如果一个字段存在blank=True,表单验证将允许一个空值。如果一个字段blank=False,则表单验证时必须输入数据。
choices
Field.choices

为字段提供可选选项的列表或元组。如果提供该选项,默认的窗体部件将是一个包含标准文本字段的选择框。

每个元组的第一个元素是要存储的实际值,而第二个元素是显示在窗体上的名称。例如:

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

一般来说,这是最好的一个模型类里面定义的选择,每个值定义一个合适的命名常数:

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)

还可以使用二维组的方式:

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

每个元组的第一个元素的名称是适用于组。第二个元素是一个可迭代的二元组,每个2元组包含一个值和一个可读名称的选项。也可以组合与取消分组,使用一个单一的列表(例如,在这个例子中的 unknown)。

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

最后,请注意,可以选择任何可迭代的对象-不一定是列表或元组。这使您可以动态构造选择。
db_column
Field.db_column

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

如果您的数据库列名是一个SQL的保留字,或包含Python变量名中不允许的字符 – 特别是连字符时使用。
db_index
Field.db_index

如果为True,django-admin.py sqlindexes 命令将为该字段输出CREATE INDEX 语句。
db_tablespace
Field.db_tablespace

如果该字段索引数据库表空间(database tablespace)的名字,则使用此字段的索引。默认是项目的 DEFAULT_INDEX_TABLESPACE 设置,如果设置或模型有db_tablespace。如果后端不支持用于索引的表空间,则忽略此选项。
default
Field.default

字段的默认值。可以是一个值也可以是可调用对象。 如果是调用,则每次都将创建一个新的对象。

默认值不能是一个可变对象(模型实例,列表,集合等),作为到同一个实例的参考,该对象将用作所有新的模型实例中的默认值。相反,在一个可调用的对象中封装所需的默认值。例如,如果你有一个自定义JSONField,并希望指定一个作为默认的字典,使用一个lambda表达式如下:

contact_info = JSONField("ContactInfo", default=lambda:{"email": "to1@example.com"})

editable

Field.editable

如果为 False,将不会被显示在管理员或任何其他 ModelForm。默认值是true。

error_messages

Field.error_messages

error_messages 参数让你可以覆盖默认的消息。通过字典中的键匹配你想要覆盖的错误消息。错误消息的键包括null, blank, invalid, invalid_choice, 和 unique。
help_text
Field.help_text

用窗体控件显示的额外的“help”文本。这是非常有用的文档,即便你的字段上没有使用。

注意,这个值不是自动生成的表单HTML转义。也就是说你需要在help_text中包含HTML元素。例如:

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

另外,你还可以使用纯文本或用django.utils.html.escape()对任何HTML特殊字符进行转义。
primary_key
Field.primary_key

如果为True,这个字段是该模型的主键。

如果你不为你模型中的任何字段指定primary_key=True,Django将自动添加自增字段 AutoField作为主键。所以,你不需要设置任何字段为primary_key=True,除非你想覆盖默认的主键。如需更多信息请查阅Automatic primary key fields

primary_key=True意味着null=False 而 unique=True。每个对象只允许拥有一个主键。
unique
Field.unique

如果为True,则该字段必须是整个表中唯一的。

这是强制在数据库和模型上的验证。如果试图将一个重复的值保存在模型中的unique字段,一个django.db.IntegrityError错误将被通过模型的save()方法返回。

此选项适用于除 ManyToManyField 和 FileField之外的所有字段类型。

注意,当unique 为 True时,你不需要指定db_index,因为unique暗示创建索引。


unique_for_date

Field.unique_for_date


如果要求在某个日期内,该字段值在数据表中是唯一的(就不存在时期和字段值都相同的记录),那就可以将 unique_for_date 设置为某个 DateField 或 DateTimeField 的名称。

例如,假设你有一个声明了 unique_for_date=”pub_date” 的 title 字段,那么 Django 就不会允许出现 title 和 pub_date 相同的两条记录。

它作用于 Django 的管理后台和表单层级,而非数据库层级。

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 field names).

字段类型(Field types)

AutoField
class AutoField(**options)

它是一个根据 ID 自增长的 IntegerField 字段。通常,你不必直接使用该字段。如果你没在别的字段上指定主键,Django 就会自动添加主键字段。详见 自增主键字段(Automatic primary key fields)。

BigIntegerField
class BigIntegerField([**options])

64位的整数,跟IntegerField相似,数值范围从-9223372036854775808 到 9223372036854775807。该字段默认的窗体控件为 TextInput

BooleanField
class BooleanField(**options)

一个布尔值(true/false)字段。

Django 的管理后台用CheckboxInput来表现该字段类型。如果想让该字段接受 null 值,只需用NullBooleanField 替代即可。

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

它是一个字符串字段,对小字符串和大字符串都适用。

对于更大的文本,应该使用 TextField 。

Django 的管理后台用 <input type="text"> (单行输入框) 来表示这种字段。

CharField 有一个必须传入的参数:

CharField.max_length字段的最大字符数。它作用于数据库层级和 Django 的数据验证层级。

注意

如果你正在编写的应用要求满足多种数据库,那么你就要注意不同数据库对 max_length 有不同的限制。详见 数据库 (database backend notes) 。

MySQL 用户请注意:

如果你使用 MySQLdb 1.2.2 和 utf8_bin 字符集(非默认设置),有几点注意事项要格外留意。详见 MySQL 数据库 (MySQL database notes) 。

CommaSeparatedIntegerField
class CommaSeparatedIntegerField(max_length=None[, **options])

它用来存放以逗号间隔的整数序列。和 CharField 一样,必须为它提供 max_length 参数。而且要注意不同数据库对 max_length 的限制。

DateField
class DateField([auto_now=False, auto_now_add=False, **options])

该字段利用 Python 的 datetime.date 实例来表示日期。下面是它额外的可选参数:

DateField.auto_now

每一次保存对象时,Django 都会自动将该字段的值设置为当前时间。一般用来表示 ”最后修改” 时间。要注意使用的是当前日期,而并非默认值,所以你不能通过重写默认值的办法来改变保存时间。

DateField.auto_now_add

在第一次创建对象时,Django 自动将该字段的值设置为当前时间,一般用来表示对象创建时间。它使用的同样是当前日期,而非默认值。Django 管理后台使用一个带有 Javascript 日历的 <input type="text"> 来表示该字段,它带有一个当前日期的快捷选择。那个 JavaScript 日历总是以星期天做为一个星期的第一天。

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

该字段利用 datetime.datetime 实例表示日期和时间。该字段所按受的参数和 DateField 一样。

Django 的管理后台使用两个 <input type="text"> 分别表示日期和时间,同样也带有 JavaScript 快捷选项。

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

它是使用 Decimal 实例表示固定精度的十进制数的字段。它有两个必须的参数:

DecimalField.max_digits

数字允许的最大位数

DecimalField.decimal_places

小数的最大位数

例如,要存储的数字最大值是999,而带有两个小数位,你可以使用:

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

要存储大约是十亿级且带有10个小数位的数字,就这样写:

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

Django 管理后台使用 <input type="text"> (单行输入框) 表示该字段。

EmailField
class EmailField([max_length=75, **options])

它是带有 email 合法性检测的A CharField 。

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

文件上传字段

注意

该字段不支持 primary_key 和 unique 参数,否则会抛出 TypeError 异常。

它有一个必须的参数:

FileField.upload_to 用于保存文件的本地文件系统。它根据 MEDIA_ROOT 设置确定该文件的 url 属性。该路径可以包含 时间格式串 (strftime formatting),可以在上传文件的时候替换成当时日期/时间(这样,就不会出现在上传文件把某个目录塞满的情况了)。该参数也可以是一个可调用项,比如是一个函式,可以调用函式获得包含文件名的上传路径。这个可调用项必须要接受两个参数,并且返回一个保存文件用的 Unix-Style 的路径(用 / 斜杠)。两个参数分别是:


参数 描述
instance 定义了当前 FileField 的 model 实例。更准确地说,就是以该文件为附件的 model 实例。大多数情况下,在保存该文件时, model 实例对象还并没有保存到数据库,这是因为它很有可能使用默认的AutoField,而此时它还没有从数据库中获得主键值。(用法见oteam的http://oteam.cn/2008/10/4/dynamic-upload-paths-in-django/)
filename 上传文件的原始名称。在生成最终路径的时候,有可能会用到它。

还有一个可选的参数:

FileField.storage 负责保存和获取文件的对象。详见  Managing files

Django 管理后台使用 <input type="file"> (一个文件上传的部件) 来表示这个对象。

在 model 中使用 FileField 或 ImageField (稍后会提到) 要按照以下的步骤:

  1. 在项目配置文件中,你要定义 MEDIA_ROOT ,将它的值设为用来存放上传文件的目录的完整路径。(基于性能的考虑,Django 没有将文件保存在数据库中。) ,然后定义 MEDIA_URL ,将它的值设为表示该目录的网址。要确保 web 服务器所用的帐号拥有对该目录的写权限。
  2. 在 model 里面添加 FileField 或 ImageField ,并且确认已定义了 upload_to 项,让 Django 知道应该用 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 formatting); '%Y'是四位的年分,'%m' 是两位的月分, '%d' 是两位的日子。如果你在2007年01月15号上传了一个文件,那么这个文件就保存在 /home/media/photos/2007/01/15 目录下。

如果你想得到上传文件的本地文件名称,文件网址,或是文件的大小,你可以使用 name, url 和 size 属性;详见 管理文件 (Managing files)

注意:在上传文件时,要警惕保存文件的位置和文件的类型,这么做的原因是为了避免安全漏洞。对每一个上传文件都要验证,这样你才能确保上传的文件是你想要的文件。举个例子,如果你盲目地让别人上传文件,而没有对上传文件进行验证,如果保存文件的目录处于 web 服务器的根目录下,万一有人上传了一个 CGI 或是 PHP 脚本,然后通过访问脚本网址来运行上传的脚本,那可就太危险了。千万不要让这样的事情发生!

默认情况下,FileField 实例在数据库中的对应列是 varchar(100) ,和其他字段一样,你可以利用 max_length 参数改变字段的最大长度。

FileField 和 FieldFile

class FieldFile

当在模型中使用FileField 时,将会获得 FieldFile 的实例作代理,去访问底层文件。该类有些适用于文件数据的属性和方法。

FieldFile.url

通过只读的方式调用底层存储(Storage)类的 url() 方法,来访问该文件的相对URL。

FieldFile.open(mode=’rb’)

跟标准Python的 open() 方法一样,用该模型实例指定的模式打开相关文件。

FieldFile.close()

跟标准Python的 file.close() 方法一样,关闭该文件与此实例的关联。

FieldFile.save(namecontentsave=True)

这种方法将文件名和文件内容传递到该字段的存储类,然后将文件存储到该模型字段。如果想在模型中用 FileField 实例,手动关联文件数据,则用 save() 方法保存文件数据。

该方法需要两个必须的参数:name 文件的名称, content 包含文件内容的对象。save 参数是可选的,主要是控制保存后的文件实例是否可更改。默认是 True 。

需要注意的是,content 参数是 django.core.files.File 的一个实例,不是Python的内置文件对象。你可以使用他从现有的Python文件对象中构建一个文件,如下所示:

from django.core.files import File
# Open an existing file using Python's built-in open()
f = open('/tmp/hello.world')
myfile = File(f)

或者,你也可以用Python的字符串构建一个,如下所示:

from django.core.files.base import ContentFile
myfile = ContentFile("hello world")

想了解更多信息,请参阅 Managing files 。

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.gif。

FilePathField.recursive

可选参数。它的值是 True 或 False。默认值是 False。它指定是否包含 path 下的子目录。

FilePathField.allow_files

该项属于Django1.5新增内容。可选参数,它的值是 True 或 False。默认值是 True。它指定是否包含指定位置的文件。该项或 allow_folders 必须有一个是 True。

FilePathField.allow_folders

Django1.5新增内容。可选参数,他的值是True或False。默认是False。它指定是否包含指定位置的文件夹。该项或allow_files必须有一个是 True。

当然,这些参数可以同时使用。

前面已经提到了 match 只匹配文件名称,而不是文件路径。所以下面这个例子:

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

将匹配 /home/images/foo.gif ,而不匹配 /home/images/foo/bar.gif。这是因为 match 只匹配文件名 (foo.gif 和 bar.gif).

默认情况下, FilePathField 实例在数据库中的对应列是 varchar(100) 。和其他字段一样,你可以利用 max_length 参数改变字段的最大升序。

FloatField
class FloatField([**options])

该字段在 Python 中使用 float 实例来表示一个浮点数。

Django 管理后台用 <input type="text"> (一个单行输入框) 表示该字段。

ImageField
class ImageField(upload_to=None[, height_field=Nonewidth_field=Nonemax_length=100**options])

和 FileField 一样,只是会验证上传对象是不是一个合法的图象文件。它有两个可选参数:

ImageField.height_field

保存图片高度的字段名称。在保存对象时,会根据该字段设定的高度,对图片文件进行缩放转换。

ImageField.width_field

保存图片宽度的字段名称。在保存对象时,会根据该字段设定的宽度,对图片文件进行缩放转换。除了那些在 FileField 中有效的参数之外, ImageField 还可以使用 File.height 和 File.width 两个属性。详见管理文件 (Managing files)(但我个人wrongway并没有找到这两个参数的介绍)。

使用该字段要求安装 Python Imaging Library(PIL).
默认情况下, ImageField 实例对应着数据库中的  varchar(100) 列。和其他字段一样,你可以使用 max_length 参数来改变字段的最大长度。

IntegerField
class IntegerField([**options])

整数字段。Django 管理后台用 <input type="text"> (一个单行输入框) 表示该字段。

IPAddressField
class IPAddressField([**options])

以字符串形式(比如 192.0.2.30)表示 IP 地址字段。Django 管理后台使用 <input type="text"> (一个单行输入框) 表示该字段。

GenericIPAddressField
class GenericIPAddressField([protocol=bothunpack_ipv4=False,**options])

Django1.4中新增选项。以字符串的形式(比如 192.0.2.30 或 2a02:42fe::4)表示 IPv4或IPv6地址字段。该字段默认的表单控件为 TextInput

GenericIPAddressField.protocol

验证输入协议的有效性。默认值是 ‘both’ 也就是IPv4或者IPv6。该项不区分大小写。

GenericIPAddressField.unpack_ipv4

解释IPv4映射的地址,像   ::ffff:192.0.2.1  。如果启用该选项,该地址将必解释为 192.0.2.1 。默认是禁止的。只有当 protocol 被设置为 ‘both’ 时才可以启用。

NullBooleanField
class NullBooleanField([**options])

与 BooleanField 相似,但多了一个 NULL 选项。建议用该字段代替使用 null=True 选项的 BooleanField 。Django 管理后台使用 <select> 选择框来表示该字段,选择框有三个选项,分别是 “Unknown”, “Yes” 和 “No” 。

PositiveIntegerField
class PositiveIntegerField([**options])

和 IntegerField 相似,但字段值必须是非负数。

PositiveSmallIntegerField
class PositiveSmallIntegerField([**options])

和 PositiveIntegerField 类似,但数值的取值范围较小,受限于数据库设置。

SlugField
class SlugField([max_length=50**options])

Slug 是一个新闻术语,是指某个事件的短标签。它只能由字母,数字,下划线或连字符组成。通赏情况下,它被用做网址的一部分。

和 CharField 类似,你可以指定 max_length (要注意数据库兼容性和本节提到的 max_length )。如果没有指定 max_length ,Django 会默认字段长度为50。

该字段会自动设置 Field.db_index 为 True。

基于其他字段的值来自动填充 Slug 字段是很有用的。你可以在 Django 的管理后台中使用 prepopulated_fields 来做到这一点。

SmallIntegerField
class SmallIntegerField([**options])

和 IntegerField 类似,但数值的取值范围较小,受限于数据库的限制。

TextField
class TextField([**options])

大文本字段。Django 的管理后台使用 <textarea> (一个多行文本框) 表示该字段。

MySQL 用户请注意

如果你正在使用 MySQLdb 1.2.1p2 和 utf8_bin 字符集(非默认设置),有几点注意事项要格外留意,详见 MySQL database notes 。

TimeField
class TimeField([auto_now=Falseauto_now_add=False**options])

该字段使用 Python 的 datetime.time 实例来表示时间。它和 DateField 接受同样的自动填充的参数。

Django 管理后台使用一个带 Javascript 快捷链接 的 <input type="text"> 表示该字段。

URLField
class URLField([max_length=200**options])

保存 URL 的 CharField 。它有一个额外的可选参数:

Django 管理后台使用 <input type="text"> (一个单行输入框) 表示该字段。

和所有 CharField 子类一样,URLField 接受可选的 max_length 参数,该参数默认值是200。

在Django1.5管理后台中,上面的输入部件将显示为可点击的链接。

 

关联关系字段 (Relationship fields)

Django 也定义了一组用来表示关联关系的字段。

ForeignKey
class ForeignKey(othermodel[, **options])

这是一个多对一关系。必须为它提供一个位置参数:被关联的 model 类。

要创建递归关联时–与对象自己做多对一关系,那就使用 models.ForeignKey('self') 。

如果你要与某个尚未定义的 model 建立关联 ,就使用 model 的名称,而不是使用 model 对象本身:

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

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

要与其他应用中的 model 相关联,你要用完整的应用标签来显式地定义关联。例如,如果上面的 Manufacturer model 定义在另外一个名为 production 的应用中,你只要用:

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

在解决两个应用双向依赖时,这种引用方法非常有用。

数据库表现 (Database Representation)

Django 使用该字段名称+ "_id" 做为数据库中的列名称。在上面的例子中, Car model 对应的数据表中会有一个 manufacturer_id 列。(你可以通过显式地指定 db_column来改变该字段的列名称)。不过,除非你想自定义 SQL ,否则没必要更改数据库的列名称。

参数 (Arguments)

ForeignKey 接受下列这些可选参数,这些参数定义了关系是如何运行的。

ForeignKey.limit_choices_to

它是一个包含筛选条件和对应值的字典 (详见see 制作查询(Making queries)),用来在 Django 管理后台筛选关联对象。例如,利用 Python 的 datetime 模块,过滤掉不符合筛选条件关联对象:

limit_choices_to = {'pub_date__lte': datetime.now}

只有 pub_date 在当前日期之前的关联对象才允许被选。

也可以使用 Q 对象来代替字典,从而实现更复杂的筛选,详见 复杂查询 (complex queries)

limit_choices_to 对于在管理后台显示为 inline 的关联对象不起作用。

ForeignKey.related_name

反向名称,用来从被关联字段指向关联字段。在 被关联对象文档 (related objects documentation) 中有详细介绍和范例。注意,在你定义 抽象 model (abstract models)时,你必须显式指定反向名称; 只有在你这么做了之后, 某些特别语法 (some special syntax) 才能正常使用。

ForeignKey.to_field

指定当前关系与被关联对象中的哪个字段关联。默认情况下,to_field 指向被关联对象的主键。

ForeignKey.on_delete

当由一个 ForeignKey 引用的对象被删除,默认情况下,Django模拟SQL的 ON DELETE CASCADE 来删除对象的 ForeignKey 关系。这样可以覆盖指定的 on_delete 参数。比如,你有一个可为空的 ForeignKey ,你想他引用的对象被删除时,该项为空。

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

django.db.models 中的 on_delete 存在以下设置值:

CASCADE

级联删除默认值。

PROTECT

阻止删除 django.db.IntegrityError 的子类 ProtectedError 引用的对象。

SET_NULL

设置 ForeignKey 为空。只有 null 为 True 时才可设置。

SET_DEFAULT

设置 ForeignKey 的默认值,而且必须得设置。

SET()

设置 ForeignKey 的值传递给 SET() ,并允许可调用的对象调用它。大多数情况下通过调用是必要的,这样可以避免执行查询时models.py被导入。

def get_sentinel_user():
    return User.objects.get_or_create(username='deleted')[0]

class MyModel(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET(get_sentinel_user))

DO_NOTHING

不采取任何行动。如果你的数据库后端强制引用完整性,这将导致 IntegrityError 错误,除非手动添加SQL数据库中的 ON DELETE  字段进行约束。

ManyToManyField
class ManyToManyField(othermodel[, **options])

用来定义多对多关系。必须给它一个位置参数:被关联的 model 类。工作方式和 ForeignKey 一样, 连 递归关联 (recursive) and 延后关联 (lazy) 都一样。

数据库表示 (Database Representation)

Django 创建一个中间表来表示多对多关系。默认情况下,中间表的名称由两个关系表名结合而成。由于某些数据库对表名的长度有限制,所以中间表的名称会自动限制在64个字符以内,并包含一个不重复的哈希字符串。这意味着,你可能看到类似 author_books_9cdf4 这样的表名称;这是很正常的。你可以使用 db_table 选项手动指定中间表名称。

参数 (Arguments)

ManyToManyField 接受下列可选参数,这些参数定义了关系是如何运行的。

ManyToManyField.related_name

和 ForeignKey.related_name 用法一样。

ManyToManyField.limit_choices_to

和 ForeignKey.limit_choices_to 用法一样。

limit_choices_to 对于通过 through 参数指定了中介表的 ManyToManyField 不起作用。

ManyToManyField.symmetrical

只要定义递归的多对多关系时起作用。假调有下面这样一个 model :

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

Django 处理该 model 时,Django 会发现这个一个关联自己的递归 ManyToManyField ,所以 Django 不会给该字段添加一个指向 Person 类的 person_set 属性,而是把ManyToManyField 视为对称的–也就是说,如果我是你的朋友,那么你自然也就是我的朋友。

如果不想将递归的多对多关系设为对称的,那你就指定 symmetrical 为 False。这样就会强迫 Django 添加反向名称,从而将该 ManyToManyField 关联改为非对称的。

ManyToManyField.through

Django 会自动生成一张表来管理多对多关系。但是,如果你想手动指定中间表,你可以用 through 选项来指定 model 使用另外某个 model 来管理多对多关系。而这个 model 就是中间表所对应的 model 。(我将through所指定的中间表称为中介表)。当你想使用 多对多关系中的其他数据 (extra data with a many-to-many relationship) 时,一般要用到这个选项。

ManyToManyField.db_table

指定数据库中保存多对多关系数据的表名称。如果没有提供该选项,Django 就会根据两个关系表的名称生成一个新的表名,做为中间表的名称。

OneToOneField
class OneToOneField(othermodel[, parent_link=False**options])

用来定义一对一关系。笼统地讲,它与声明了 unique=True 的 ForeignKey 非常相似,不同的是使用反向关联的时候,得到的不是一个对象列表,而是一个单独的对象。

在某个 model 扩展自另一个 model 时,这个字段是非常有用的;例如: 多表继承 (Multi-table inheritance) 就是通过在子 model 中添加一个指向父 model 的一对一关联而实现的。

必须给该字段一个参数:被关联的 model 类。工作方式和 ForeignKey 一样,连 递归关联 (recursive) 和 延后关联 (lazy) 都一样。

此外,OneToOneField 接受 ForeignKey 可接受的参数,只有一个参数是 OnetoOneField 专有的:

OneToOneField.parent_link

如果为 True ,并且作用于继承自某个父 model 的子 model 上(这里不能是延后继承,父 model 必须真实存在),那么该字段就会变成指向父类实例的引用(或者叫链接),而不是象其他 OneToOneField 那样用于扩展父类并继承父类属性。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值