django1.8 model (2): Field types

本文档详细介绍了Django1.8中的Model字段类型及其选项,包括Field options如null、blank、choices等,以及各种Field types如AutoField、CharField、BooleanField等。文章还提到了ForeignKey和ManyToManyField等关系字段的用法,以及如何自定义字段行为。
摘要由CSDN通过智能技术生成

此文翻译自djang1.8.2官方文档

Model field reference

这篇文档包含了django提供的字段的options和types的所有的API.

See also
如果内置的字段不能满足需求,你可以试试django-localflavor,它包含了用于特定的国家或文化的各种各样的代码.或者你可以很容易的定制你自己的模型字段.

Note
严格来说,这些模型应该在django.db.models.fields里定义,但是为了方便,他们导入到了django.db.models;标准用法是使用from django.db import models,这样使用字段,models.Field.

Field options

下面的参数所有字段类型都可用,都是可选的.

null

Field.null
如果是True,django会把空值作为NULL存储在数据库里.默认是False.
避免在字符类型的字段(例如CharField,TextField)上使用null,因为如果null=True,空字符串仍然作为空字符串存储,这就是说”没有数据”有2个可能的值:NULL和空字符串.大多数情况下,”没有数据”有2个可能的值是多余的;django的惯例是是哦用空字符串,而不是NULL.
对于字符类型字段和非字符类型字段,如果你希望允许表单提交空值,就应该设置blank=True,因为null参数值作用于数据库存储.

Note
When using the Oracle database backend, the value NULL will be stored to denote the empty string regardless of this attribute.

如果你希望BooleanField能接受null值,请使用NullBooleanField.

blank

Field.blank
如果是True,字段允许是空.默认是False.
注意blank和null不同.null是用于数据库,但blank是用于验证.如果一个字段blank=True,表单验证则允许输入空字符.如果blank=False,字段是必填的.

choices

Field.choices
由2个元素的可迭代对象组成的可迭代对象当作字段的选项.如果有这个参数,默认的表单widget将是一个下拉选而不是标准的文本字段,值为这些选项.
每个元组的第一个元素是设置的模型的值,第二个元素是给人看的名称.例如:

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

通常,最好在模型类里定义choices,给每个值定义一个合适的名字常量:

from django.db import models

class Student(models.Model):
    RRESHMAN = '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)

然而你可以在模型类外定义一个choices list然后引用它,在模型内定义choices能使类自己保留类信息,并使choices容易引用(例如,Student.SOPHOMORE能在任何地方工作只要导入了Student模型).
另外,出于组织代码的目的,你也可以将选线放到named groups里:

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

每个元组的第一个元素是组的名称.第二个元素是一个由2元素元组组成的可迭代对象,每个2元素元组包含一个值和作为选项的给人看的名称.分组的选项可以和未分组的选项放到一起(就像例子中的unknown选项).
每个有choices的模型字段,django会为字段的值增加一个查询human-readable名称.详情参考数据库API中的get_FOO_display().
注意,choices可以是任何可迭代对象-不一定是列表或元组.你能动态的构造choices.但是如果你使用动态的choices,你最好使用一个有外键的数据库表.choices意味着没有很多改变的静态数据.

django1.7新增
除非字段设置了blank=False,和default,否则下拉选就会渲染一个”——–”标签.在choices里添加一个包含None的元组可以重写这个行为;例如(None, ‘Your String For Display’).另外,你可以使用一个空字符串代替None,只要适用-例如CharField.

db_column

Field.db_column
该字段使用的数据库字段名称.
如果你的数据库字段名是SQL关键字,或者有字符属于非python标识符-比如,连接符(hyphen,-)-这没有问题.django会对字段和表名做合适的引用.

db_index

Field.db_index
如果是True,django-admin sqlindexed会为这个字段输出一个CREATE INDEX语句.

db_tablespace

Field.db_tablespace
如果该字段有索引,database tablespace的名称会用于字段索引.默认是项目的DEFAULT_INDEX_TABLESPACE setting,或是模型的db_tablespace.如果数据库引擎不支持索引的tablespace,那么这个选项会被忽略.

default

Field.default
字段的默认值.可以是一个值或可调用对象.如果是可调用对象,每次新建对象时都会被调用.
默认值不能是可变对象(模型实例,列表,集合等), as a reference to the same instance of that object would be used as the default value in all new model instances.Instead,将想要的默认值封装到一个可调用对象里.例如,如果你有一个自定义的JSONField,想要指定一个字典作为默认值,使用下面的方法:

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

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

注意匿名函数不能用于字段的可选项(例如default)因为不能被migrations序列化.
默认值用于新建模型实例且没有提供字段的值.如果字段是主键,且设置了None,默认值也可以使用.

django1.8更改
在上一个版本中default不能用于None primary key.

editable

Field.editable
如果是False,该字段将不在admin或其他ModelForm里显示.他们也不需要验证.默认为True.

error_message

Field.error_messages
error_message参数能重写默认的字段抛出的信息.传递一个包含你想重写的错误消息的key的字典.
错误消息key包含null,blank,invalid,invalid_choice,unique和unique_for_date.其余的错误消息key在下面的Field types部分有介绍.

django1.7新增
增加unique_for_date错误消息key.

help_text

Field.help_text
在表单widget里显示的额外的’帮助’文本.如果你的字段不用于表单,也可用于文档.
注意:这个值在自动生成的表单里不是HTML-escape的.如果需要的话,可以在help_text里包含HTML.例如:

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

或者你可以使用普通文本和django.utils.html.escape()来转义HTML特殊字符.你转义的任何帮助文本可能来自于不信任的用户,要避免跨站脚本攻击(cross-site scripting attack).

primary_key

Field.primary_key
如果是True,该字段就是模型的主键.
如果你没有指定模型中任何字段为primary_key=True,django会自动添加一个AutoField来充当主键,所以你不需要在任何字段设置primary_key=True除非你想重写默认的主键行为.
primary_key意味着null=False和unique=True.一个对象只能有一个主键.
主键是只读的.如果你改变一个已有对象的主键的值然后保存,会创建一个新对象.

unique

Field.unique
如果是True,该字段在表中必须唯一.
这是通过模型验证在数据库层面强制执行的.如果你保存的对象的unique字段的值重复了,模型的save()方法会抛出django.db.IntegrityError.
这个选项所有字段都可使用,除了ManyToManyField,OneToOneField和FileField.
注意当unique是True,你就没必要自定db_index了,因为唯一字段会创建索引.

unique_for_date

Field.unique_for_date
设置为DateField或DateTimeField字段,那么该字段的日期值就必须唯一.
例如,你有一个字段title设置了unique_for_date=”pub_date”,那么django就不允许2条记录有同样的title和pub_date.
注意:如果你设置为DateTimeField,只有日期部分起作用.另外,如果USE_TZ是True,对象保存时,会按照当前时区进行检查.
这是在模型验证时通过Model.validate_unique()强制执行的,而不是数据库层.如果unique_for_date限制的字段不是ModelForm的一部分(例如,其中一个字段不在list中或者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
字段的给人读的名称.如果没有别名(verbose name),django会自动生成一个,使用字段的属性名,下划线会转换成空格.

validators

Field.validators
改字段的验证器(validators)列表.
- Registering and fetching lookups
Field implements the lookup registration API. The API can be used to customize which lookups are available for a field class, and how lookups are fetched from a field.

Field types

AutoField

class AutoField(**options)
根据可用的ID自增长的IntegerField.通常不直接使用;如果你不指定,主键字段会自动添加到你的模型.

BigIntegerField

class BigIntegerField([**options])
64位整数.很像IntegerField,不过数字范围是从-9223372036854775808到9223372036854775807.该字段默认的表单widget是TextInput(<input type=”text” …>).

BinaryField

class BinaryField([**options])
存储原始二进制数据的字段.It only supports bytes assignment.请注意,这个字段功能有限.例如,不能用queryset中对该字段值使用filter.

滥用BinaryField
虽然你可能想在数据库中存储文件,但99%的情况下这都是烂设计.这个字段不是存储静态文件的理想方式.

BooleanField

class BooleanField(**options)
一个真/假字段.
该字段默认的表单widget是CheckboxInput(<input type=’checkbox’ …>).
如果你想接受null值,使用NullBooleanField.
如果Field.default没有定义,BooleanField的默认值是None.

CharField

class CharField(max_length=None[, **options])
字符串字段,小的打的字符串.大量字符串使用TextField.
该字段默认的表单部件是TextInput.
CharField有一个必需的参数:
- CharField.max_length
字段的最大长度.max_length在数据库层强制执行,有django验证.
注意:
如果你的应用必须适配多个数据库引擎,你得小心某些引擎的max_length的限制.详情参考database backend notes.
MySQL使用者:
如果你在MySQLdb1.2.2中使用这个字段,且使用utf8_bin collation,有些细节要注意,详情参考MySQL database notes.

CommaSeparatedIntegerField

class CommaSeparatedIntegerField(max_length=None[, **options])
用逗号分隔的整数字段.和CharField一样,max_length字段是必需的,不同的数据库有区别,要注意.

DateField

class DateField([auto_now=Flase, auto_now_add=Flase, **options])
一个日期,表现为datetime.date实例.有一些额外的,可选参数.
- DateField.auto_now
每次对象保存时自动设置字段为当前时间.用作”最后修改”时间戳.注意总是使用当前日期,它不是默认值,你可以重写.
- DateField.auto_now_add
对象第一次创建时自动设置字段为当前时间.注意总是使用当前日期,它不是默认值,你可以重写.

该字段的默认表单部件是TextInput.admin添加了一个javascript日历和一个”今天”的快捷方式.包含了一个invalid_date错误消息key.
可选项auto_now_add,auto_now和默认的可选项是互斥的.这些可选项的冲突会造成错误.
注意:
目前,设置auto_now或auto_now_add为True会导致字段设置editable=Flase和blank=True.
注意:
auto_now和auto_now_add可选项重视使用新建或修改时的时间的默认时区.如果你有不同需求,你可以使用考虑使用你自己的方法或者重写save()方法,而不是使用auto_now或auto_now_add;或者使用DateTimeField代替DateField,并决定显示时间时怎么把datetime转换成date.

DateTimeField

class DateTimeField([auto_now=False, auto_now_add=False, **options])
日期和时间,表现为datetime.datetime实例.和DateField的额外参数一样.
该字段默认的表单部件是一个TextInput.admin使用2个分开的TextInput部件,有javascript快键方式.

DecimalField

class DecimalField(max_digits=None, decimal_places=None[, **options])
定义精度的十进制数,表现为Decimal实例.有2个必需参数:
- 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)

该字段默认的表单部件是TextInput
注意:
FloatField和DecimalField的区别,详细信息请查看参考文档.

DurationField

django1.8新增
class DurationField([**options])
存储一段时间的字段-python的timedelta.使用PostgreSQL时,数据类型是interval,使用oracle时数据类型是INTERVAL DAY(9)到SECOND(6).其他情况使用代表微秒的bigint.

注意:
大多数情况下可以用DurationField做算术运算.但是除了PostgreSQL外的所有数据库,比较DurationField实例的值和DateTimeField实例的值不会像预期一样工作.

EmailField

class EmailField([max_length=254, **options])
值为有效的email地址的CharField.使用EmailValidator来验证输入.

django1.8更改
为了兼容RFC3696/5321,默认的max_length从75增长到254

FileField

class FileField([upload_to=None, max_length=100, **options])
一个上传文件字段.

注意
不支持primary_key和unique参数,如果使用了会抛出TypeError.

有2个可选参数:
- FileField.upload_to
django1.7更改
之前版本的django中upload_to是必需的
一个本地文件系统路径,添加到MEDIA_ROOT设置后面,决定url属性的值.
This path may contain strftime() formatting, which will be replaced by the date/time of the file upload (so that uploaded files don’t fill up the given directory).
也可以是一个可调用对象,例如一个函数,调用它可以得到一个上传路径,包含了文件名.这个可调用对象必须要能接受2个参数,并返回一个Unix-style路径(有斜杠结尾).这2个参数是:


ArgumentDescription
instanceAn instanceof the model where the FileField is defined. More specifically, this is the particular instance where the current file is being attached.In most cases, this object will not have been saved to the database yet, so if it uses the default AutoField, it might not yet have a value for its primary key field.
filenameThe filename that was originally given to the file. This may or may not be taken into account when determining the final destination path.

- FileField.storage
A storage object, which handles the storage and retrieval of your files. See Managing files for details on how to provide this object.
改字段默认的表单部件是ClearableFileInput.
在模型里使用FileField或ImageFiled有这几步
1. 在settings文件里,定义MEDIA_ROOT为你想django存储上传文件的完整路径.(为了性能,这些文件不存储在数据库)定义MEDIA_URL为目录的base public 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’是2位月,’%d’是2位天.如果你在Jan.15,2007上传一个文件,文件就会保存在目录/home/media/photos/2007/01/15.
如果你想查询上传文件在磁盘上的文件名或者文件的大小,你可以使用分别使用name和size属性.详情请查看参考文档.

注意:
文件保存是作为在数据库里保存模型的一部分.所以在模型保存之前,磁盘上实际的文件名是不可靠的.

The uploaded file’s relative URL can be obtained using the url attribute. Internally, this calls the url() method of the underlying Storage class.
注意当你处理上传文件时,你应该关注你把文件存到哪里,文件是什么类型,小心有安全问题.验证所有的上传文件.例如,如果盲目允许某人不经过验证,上传文件到你的服务器的document root,那么某些人可能上传CGI或PHP脚本并通过访问脚本的URL来执行脚本.不要这么做.
HTML文件也要注意,因为它能被浏览器执行(虽然不是服务器执行),会导致XSS或CSRF攻击的安全问题.
FileField实例在数据库里创建varchar字段,默认长度是100个字符.就像其他字段一样,你可以使用max_length来改变最大长度.

FileField and FieldFile

class FieldFile
当你访问一个模型的FileField时,你会得到一个FieldFile的实例,作为代理来访问underlying file.除了继承自django.core.files.File的功能外,这个类还有一些属性和方法能作用于文件数据:
- FieldFile.url
只读属性,调用underlying Storage class的url()方法来访问文件的相对URL.
- FieldFile.open(mode=’rb’)
像标准的python open()方法,用指定的模式打开这个实例关联的文件.
- FieldFiel.close()
像标准的python close()方法,关闭这个实例关联的文件.
- FieldFile.save(name, content, save=True)
这个方法接受filename参数和file content参数并传递给字段的storage class,然后将模型字段和存储的文件关联起来.如果你想手动的关联模型的FileField实例和文件数据,save()方法用于持久化文件数据.
有2个必需参数:name是文件的名称,content是包含文件内容的对象.可选项save控制和字段关联的文件改变后模型实例是否保存.默认是True.
注意content参数是django.core.files.File的实例,而不是python内置的file对象.你可以用已有的python文件对象构造一个File:

from django.core.files import File
# 使用python内建方法open()打开一个存在的文件
f = open('/tmp/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,选择限制于文件系统中某个目录的文件名.有3个特殊参数,第一个是必需的:
- 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不匹配,因为match要匹配文件名(foo.png或bar.png).
FilePathField实例会在数据库里创建一个默认最大长度为100字符的varchar字段.就像其他字段一样,你可以使用max_length来改变最大长度

FloatField

class FloatField([**options])
浮点数,表现为python的float实例.
该字段的默认表单部件是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有2个额外的可选参数:
- ImageField.height_field
每次模型实例保存时,将会自动计算图片的高.
- ImageField.width_field
每次模型实例保存时,将会自动计算图片的宽.

需要Pillow库.
ImageField实例会在数据库里创建一个varchar字段,默认最大长度是100字符.就像其他字段一样,你可以使用max_length参数来改变最大长度.
该地段的默认表单部件是ClearableFileInput.

IntegerField

class IntegerField([**options])
一个整数.django支持-2147483648到2147483647,所有数据库都可用.默认的表单部件是TextInput.

IPAddressField

class IPAddressField([**options])
从1.7版开始不建议使用:建议用GenericIPAddressField代替该字段.
一个IP地址,格式化的字符串(例如,”192.0.2.30”).默认表单部件是TextInput.

GenericIPAddressField

class GenericIPAddressField([protocol=both, unpack_ipv4=False, **options])
一个IPv4或IPv6地址,格式化的字符串(例如192.0.2.30或2a02:42fe::4).默认表单部件是TextInput.
IPv6地址遵从RFC 4281规范2.2章,第三段中包含了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
对像::ffff:192.0.2.1这样的IPv4地址解包.如果这个选项启用,地址会解包为192.0.2.1.默认是不启用.只有protocol设置为’both’才可用.

如果你允许空字符串,你得允许null因为空字符串存储为null.

NullBooleanField

class NullBooleanField([**options])
像BooleanField,但允许NULL作为一个选项.使用这个字段代替null=True的BooleanField.默认的表单部件是NullBooleanSelect.

PositiveIntegerField

class PositiveIntegerField([**options])
像IntegerField,但必需是正数或零(0).django支持所有数据库从0到2147483647.接受0是为了向后兼容.

PositiveSmallIntegerField

class PositiveSmallIntegerField([**options])
像PositiveIntegerField,但只允许特定范围的值(根据不同的数据库而定).django支持所有的数据库从0到32767.

SlugField

class SlugField([max_length=50, **options])
Slug是一个报纸术语.一个slug是一个东西的简短标签,只包含字母,数字,下划线或连接号.通常用于URL.
就像CharField,你可以指定max_length.如果max_length没有指定,django会使用默认的50.
意味着设置Field.db_index为True.
常被用于从其他值来计算一个SlugField.你也可以使用prepopulated_fields在admin里自动使用.

SmallIntegerField

class SmallIntegerField([**options])
像IntegerField,但只允许特定范围的值(根据数据库而定).django支持所有数据库从-32768到32767.

TextField

class TextField([**options])
大文本字段.默认的表单部件是Textarea
django1.7更改

如果你指定了max_length属性,它将反应在自动生成的表单字段的Textarea部件上.但是不是在模型或数据库层面强制的.可以使用CharField代替.

MySQL使用者

If you are using this field with MySQLdb 1.2.1p2 and the utf8_bin collation (which is not the default),有些地方要注意,详情请查看参考文档.

TimeField

class TimeField([auto_now=False, auto_now_add=False, **options])
一个时间,表现为python的datetime.time实例.接受和DateField一样的auto_population选项.
默认的表单部件是TextInput.admin增加了一些Javascript快捷方式.

URLField

class URLField([max_length=200, **options])
A CharField for a URL.默认表单部件是TextInput.
就像所有CharField的子类一样,URLField有max_length可选参数.如果你不指定max_length,默认200.

UUIDField

django1.8新增
class UUIDField([**options])
存储全局唯一标识(universally unique identifier)的字段.使用python的UUID类.如果使用PostgreSQL,这个字段存储的是uuid字段类型,而不是char(32).
全局唯一标识可以替代作为主键的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实例.

Relationship fields

django也定义了一些表示关联的字段.

ForeignKey

class ForeignKey(othermodel[, **options])
多对一关系.需要一个位置参数:模型关联的类.
为了创建一个递归关系(recursive relationship)-一个对象和自身有多对一关系-使用models.ForeignKey(‘self’).
如果你需要在一个还没定义的模型上创建关联,你可以使用模型的名字,而不是模型对象:

from django.db import models

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

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

为了关联其他应用中的模型,你可以用完整的应用label来显式指定模型.例如,如果上面的Manufacturer模型是另一个production应用里定义的,你可以这样用:

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

这可以用于2个应用的互相导入依赖.
ForeignKey会自动创建数据库索引.你可以设置db_index为False来不启用.
你可能会像要避免索引的开销,如果你创建外键是为了一致性而不是关联查询,或者是要创建特殊的索引,比如局部索引或多列索引.
警告
不建议创建从未migrations的app到migrations app的外键(It is not recommended to have a ForeignKey from an app without migrations to an app with migrations).详情看参考文档dependencies documentation.

Database Representation

在后台,django添加”_id”到字段名后面作为数据库字段名.在上面的例子中,Car模型对应的数据库表会有一个manufacturer_id字段.(你可以显式的指定db_column).但是,你的代码从不需要处理数据库字段名,除非写自定义SQL.你只要处理模型对象的字段名.

Arguments

ForeignKey接受一些额外参数-所有都是可选的-定义了关联运作的细节.
- ForeignKey.limit_choices_to
当字段用ModelForm或admin(默认,queryset中所有对象都可以选择)渲染时限制有效的选择.可以是字典,Q对象,或者是返回字典或Q对象的可调用对象.
例如:
staff_member = models.ForeignKey(User, limit_choices_to={'is_staff': True})
这样ModelForm对应的字段就只展示is_staff=True的Users.在django admin里也是这样.
使用可调用对象也很有用,比如,使用python datetime模块来限制时间范围.

def limit_pub_date_choices():
    return {'pub_date__lte': datetime.date.utcnow()}

limit_choices_to = limt_pub_date_choices

如果limit_choices_to是适合复杂查询的Q对象,或返回Q对象,那么它只对amdin中的选择有影响,当模型的ModelAdmin中raw_id_fields中没有列出该字段时.
django1.7更改

之前的django版本不允许传递可调用对象给limit_choices_to.

注意:
如果limit_choices_to使用可调用对象,每次新表单实例化时都会调用.验证模型时也会调用,例如management命令或admin.The admin constructs querysets to validate its form inputs in various edge cases multiple times, 所以可能会调用多次.

  • ForeignKey.related_name
    The name to use for the relation from the related object back to this one. It’s also the default value for related_query_name (the name to use for the reverse filter name from the target model). See the related objects documentation for a full explanation and example. Note that you must set this value when defining relations on abstract models; and when you do so some special syntax is available.
    If you’d prefer Django not to create a backwards relation, set related_name to ‘+’ or end it with ‘+’. For example, this will ensure that the User model won’t have a backwards relation to this model:
    user = models.ForeignKey(User, related_name='+')

  • ForeignKey.related_query_name
    The name to use for the reverse filter name from the target model. Defaults to the value of related_name if it is set, otherwise it defaults to the name of the model:

# 声明有related_query_name的ForeignKey
class Tag(models.Model):
    article = models.ForeignKey(Article, 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')
  • ForeignKey.to_field
    关联对象的字段.默认,django使用关联对象的主键.

  • ForeignKey.db_constraint
    控制是否要为外键添加约束.默认是True,大多数情况适用;设置为False不利于数据完成性.有几种情况你可能会这样用:

    • 有历史遗留数据没有验证
    • 数据库分片

如果设置为False,连接到了不存在的关联对象会抛出DoesNotExist异常.
- ForeignKey.on_delete
当一个ForergnKey引用的对象删除时,django默认会效仿SQL约束ON DELETE CASCADE的行为并删除包含ForeignKey的对象.这个行为可以通过指定on_delete参数来重写.例如,如果你可ForeignKey可以为空,当引用对象删除你想设置设置为null:
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)
在django.db.models里的on_delete的可用值:
- CASCADE
级联删除;默认值
- PROTECT
通过抛出ProtectedError防止引用对象被删除,django.db.IntegrityError的子类.
- SET_NULL
设置ForeignKey为null;只有null为True才行.
- SET_DEFAULT
设置ForeignKey为默认值;必须先设置ForeignKey的默认值.
- SET()
设置ForeignKey的值为传递给SET()的值,或者传递一个可调用对象,用调用返回的值.大多数情况下,传递可调用对象能避免导入models.py时执行查询:

```python
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除非你手动的添加ON DELETE到数据库字段(可以使用inital sql)
  • ForeignKey.swappable
    django1.7新增
    Controls the migration framework’s reaction if this ForeignKey is pointing at a swappable model. If it is True - the default - then if the ForeignKey is pointing at a model which matches the current value of settings.AUTH_USER_MODEL (or another swappable model setting) the relationship will be stored in the migration using a reference to the setting, not to the model directly.
    You only want to override this to be False if you are sure your model should always point towards the swapped-in model - for example, if it is a profile model designed specifically for your custom user model.
    Setting it to False does not mean you can reference a swappable model even if it is swapped out - False just means that the migrations made with this ForeignKey will always reference the exact model you specify (so it will fail hard if the user tries to run with a User model you don’t support, for example).
    If in doubt, leave it to its default of True.

  • ForeignKey.allow_unsaved_instance_assignment
    django1.8新增
    This flag was added for backwards compatibility as older versions of Django always allowed assigning unsaved model instances.
    Django prevents unsaved model instances from being assigned to a ForeignKey field to prevent accidental data loss (unsaved foreign keys are silently ignored when saving a model instance).
    If you require allowing the assignment of unsaved instances and aren’t concerned about the data loss possibility (e.g. you never save the objects to the database), you can disable this check by creating a subclass of the field class and setting its allow_unsaved_instance_assignment attribute to True. For example:

class UnsavedForeignKey(models.ForeignKey):
    # A ForeignKey which can point to an unsaved object
    allow_unsaved_instance_assignment = True

class Book(models.Model):
    author = UnsavedForeignKey(Author)

ManyToManyField

  • Database Representation
  • Arguments

OneToOneField

Field API reference

Field attribute reference

Attributes for fields

Attributes for fields with relations

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值