django1.8 model (2): Field types

此文翻譯自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': '[email protected]'}

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個參數是:


Argument Description
instance An 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.
filename The 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章