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": "[email protected]"})

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 那樣用於擴展父類並繼承父類屬性。


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