模型欄位參考

本文包含 Field 的所有 API 參考,包括 欄位選項 和 Django 提供的 欄位類型

另請參閱

如果內建欄位無法滿足需求,您可以嘗試 django-localflavor (文件),其中包含適用於特定國家/地區和文化的各種程式碼。

此外,您可以輕鬆地撰寫您自己的自訂模型欄位

注意

欄位在 django.db.models.fields 中定義,但為了方便起見,它們會匯入到 django.db.models 中。標準慣例是使用 from django.db import models,並將欄位稱為 models.<Foo>Field

欄位選項

以下引數適用於所有欄位類型。所有引數都是選用的。

null

Field.null

如果 True,Django 會將空值以資料庫中的 NULL 儲存。預設值為 False

避免在基於字串的欄位 (例如 CharFieldTextField) 上使用 null。如果基於字串的欄位具有 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,則該欄位為必填。

提供遺失的值

blank=True 可以與具有 null=False 的欄位一起使用,但這需要在模型上實作 clean(),以便以程式設計方式提供任何遺失的值。

choices

Field.choices[來源]

以下述格式描述的對應或可迭代物件,用作此欄位的選項。如果提供選項,則會透過 模型驗證 強制執行,並且預設表單 widget 將是一個包含這些選項的選取方塊,而不是標準的文字欄位。

如果給定對應,則鍵元素是要在模型上設定的實際值,第二個元素是人類可讀的名稱。例如

YEAR_IN_SCHOOL_CHOICES = {
    "FR": "Freshman",
    "SO": "Sophomore",
    "JR": "Junior",
    "SR": "Senior",
    "GR": "Graduate",
}

您也可以傳遞一個序列,該序列本身由恰好包含兩個項目的可迭代物件組成 (例如 [(A1, B1), (A2, B2), …])。每個 tuple 中的第一個元素是要在模型上設定的實際值,第二個元素是人類可讀的名稱。例如

YEAR_IN_SCHOOL_CHOICES = [
    ("FR", "Freshman"),
    ("SO", "Sophomore"),
    ("JR", "Junior"),
    ("SR", "Senior"),
    ("GR", "Graduate"),
]

choices 也可以定義為不帶任何引數並傳回上述任何格式的可呼叫物件。例如

def get_currencies():
    return {i: i for i in settings.CURRENCIES}


class Expense(models.Model):
    amount = models.DecimalField(max_digits=10, decimal_places=2)
    currency = models.CharField(max_length=3, choices=get_currencies)

當選項是

  • I/O 繫結操作的結果時 (可能會快取),例如在相同或外部資料庫中查詢資料表,或從靜態檔案存取選項時,傳遞可呼叫物件作為 choices 會特別方便。

  • 一個大多穩定但可能不時或因專案而異的清單。此類別中的範例是使用第三方應用程式,這些應用程式提供了貨幣、國家/地區、語言、時區等眾所周知的數值清單。

在 Django 5.0 中變更

新增了對應和可呼叫物件的支援。

通常,最好在模型類別內定義選項,並為每個值定義一個適當命名的常數

from django.db import models


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

對應的鍵是要套用至群組的名稱,值是該群組內的選項,其中包含欄位值和選項的人類可讀名稱。群組化的選項可以與單個對應中的未群組化選項組合 (例如此範例中的 "unknown" 選項)。

您也可以使用序列,例如 2-tuple 的清單

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

請注意,選項可以是任何序列物件,不一定是清單或 tuple。這可讓您動態建構選項。但是,如果您發現自己正在駭入 choices 以使其動態化,您最好使用具有 ForeignKey 的適當資料庫資料表。choices 適用於很少或從不變更的靜態資料。

注意

每次 choices 的順序變更時,都會建立新的遷移。

對於每個設定了 choices 的模型欄位,Django 會將選項正規化為 2 元組的列表,並新增一個方法來檢索欄位目前值的人性化名稱。請參閱資料庫 API 文件中的 get_FOO_display()

除非在欄位上設定了 blank=False 以及 default,否則會使用選取方塊呈現包含 "---------" 的標籤。若要覆寫此行為,請在 choices 中新增包含 None 的元組;例如 (None, 'Your String For Display')。或者,您可以在適當的情況下使用空字串而不是 None,例如在 CharField 上。

列舉類型

此外,Django 提供列舉類型,您可以將其子類化,以簡潔的方式定義選項

from django.utils.translation import gettext_lazy as _


class Student(models.Model):
    class YearInSchool(models.TextChoices):
        FRESHMAN = "FR", _("Freshman")
        SOPHOMORE = "SO", _("Sophomore")
        JUNIOR = "JR", _("Junior")
        SENIOR = "SR", _("Senior")
        GRADUATE = "GR", _("Graduate")

    year_in_school = models.CharField(
        max_length=2,
        choices=YearInSchool,
        default=YearInSchool.FRESHMAN,
    )

    def is_upperclass(self):
        return self.year_in_school in {
            self.YearInSchool.JUNIOR,
            self.YearInSchool.SENIOR,
        }

它們的工作方式類似於 Python 標準函式庫中的 enum,但有一些修改

  • 列舉成員值是建構具體資料類型時要使用的引數元組。 Django 支援在此元組的末尾新增一個額外的字串值,用作人性化名稱或 labellabel 可以是一個可延遲翻譯的字串。因此,在大多數情況下,成員值將是一個 (value, label) 的 2 元組。有關使用更複雜的資料類型子類化選項的範例,請參閱下文。如果未提供元組,或最後一項不是(延遲)字串,則 label根據成員名稱自動產生

  • 在值上新增了 .label 屬性,以傳回人性化名稱。

  • 在列舉類別中新增了一些自訂屬性 – .choices.labels.values.names – 以方便存取列舉的那些獨立部分清單。

    警告

    這些屬性名稱不能用作成員名稱,因為它們會發生衝突。

  • 強制使用 enum.unique() 以確保不會多次定義值。這在欄位的選項中不太可能發生。

請注意,使用 YearInSchool.SENIORYearInSchool['SENIOR']YearInSchool('SR') 來存取或查找列舉成員可如預期般運作,成員上的 .name.value 屬性也是如此。

如果您不需要翻譯人性化名稱,可以讓它們從成員名稱推斷出來(將底線替換為空格並使用首字母大寫)。

>>> class Vehicle(models.TextChoices):
...     CAR = "C"
...     TRUCK = "T"
...     JET_SKI = "J"
...
>>> Vehicle.JET_SKI.label
'Jet Ski'

由於列舉值需要為整數的情況非常常見,因此 Django 提供了 IntegerChoices 類別。例如

class Card(models.Model):
    class Suit(models.IntegerChoices):
        DIAMOND = 1
        SPADE = 2
        HEART = 3
        CLUB = 4

    suit = models.IntegerField(choices=Suit)

也可以使用 列舉功能 API,但需要注意的是,標籤會如上述突出顯示的那樣自動產生

>>> MedalType = models.TextChoices("MedalType", "GOLD SILVER BRONZE")
>>> MedalType.choices
[('GOLD', 'Gold'), ('SILVER', 'Silver'), ('BRONZE', 'Bronze')]
>>> Place = models.IntegerChoices("Place", "FIRST SECOND THIRD")
>>> Place.choices
[(1, 'First'), (2, 'Second'), (3, 'Third')]

如果您需要支援 intstr 以外的具體資料類型,您可以將 Choices 和所需的具體資料類型子類化,例如與 DateField 搭配使用的 date

class MoonLandings(datetime.date, models.Choices):
    APOLLO_11 = 1969, 7, 20, "Apollo 11 (Eagle)"
    APOLLO_12 = 1969, 11, 19, "Apollo 12 (Intrepid)"
    APOLLO_14 = 1971, 2, 5, "Apollo 14 (Antares)"
    APOLLO_15 = 1971, 7, 30, "Apollo 15 (Falcon)"
    APOLLO_16 = 1972, 4, 21, "Apollo 16 (Orion)"
    APOLLO_17 = 1972, 12, 11, "Apollo 17 (Challenger)"

還有一些額外的注意事項需要注意

  • 列舉類型不支援具名群組

  • 由於具有具體資料類型的列舉要求所有值都符合該類型,因此無法透過建立值為 None 的成員來覆寫空白標籤。相反,請在類別上設定 __empty__ 屬性

    class Answer(models.IntegerChoices):
        NO = 0, _("No")
        YES = 1, _("Yes")
    
        __empty__ = _("(Unknown)")
    
在 Django 5.0 中變更

新增了對直接在 choices 中使用列舉類型的支援。

db_column

Field.db_column

此欄位要使用的資料庫欄名稱。如果未指定,Django 將使用欄位的名稱。

如果您的資料庫欄名稱是 SQL 保留字,或包含 Python 變數名稱中不允許的字元(特別是連字號),則沒關係。 Django 會在幕後引用欄和表格名稱。

db_comment

Field.db_comment

此欄位要使用的資料庫欄註解。對於可以直接存取資料庫且可能未查看您的 Django 程式碼的人員來說,此功能有助於記錄欄位。例如

pub_date = models.DateTimeField(
    db_comment="Date and time when the article was published",
)

db_default

Django 5.0 的新功能。
Field.db_default

此欄位的資料庫計算預設值。這可以是文字值或資料庫函數,例如 Now

created = models.DateTimeField(db_default=Now())

可以使用更複雜的運算式,只要它們是由文字和資料庫函數組成

month_due = models.DateField(
    db_default=TruncMonth(
        Now() + timedelta(days=90),
        output_field=models.DateField(),
    )
)

資料庫預設值不能引用其他欄位或模型。例如,這是無效的

end = models.IntegerField(db_default=F("start") + 50)

如果同時設定了 db_defaultField.default,則在 Python 程式碼中建立實例時,default 將優先。 db_default 仍將在資料庫層級設定,並且在 ORM 之外插入資料列或在遷移中新增欄位時使用。

如果欄位具有未設定 defaultdb_default,且未將值指派給該欄位,則會在未儲存的模型實例上以欄位值傳回 DatabaseDefault 物件。欄位的實際值由資料庫在儲存模型實例時決定。

db_index

Field.db_index

如果為 True,將為此欄位建立資料庫索引。

請改用 indexes 選項。

在可能的情況下,請改用 Meta.indexes 選項。在幾乎所有情況下,indexes 都提供了比 db_index 更多的功能。未來可能會棄用 db_index

db_tablespace

Field.db_tablespace[來源]

如果此欄位已建立索引,則此欄位索引要使用的資料庫表格空間名稱。預設值為專案的DEFAULT_INDEX_TABLESPACE設定 (如果已設定),或是模型的db_tablespace (如果有的話)。如果後端不支援索引的表格空間,則會忽略此選項。

default

Field.default

此欄位的預設值。這可以是值或可呼叫物件。如果可呼叫,則每次建立新物件時都會呼叫它。

預設值不能是可變物件(模型實例、listset 等),因為該物件的相同實例的參考將在所有新的模型實例中用作預設值。相反地,請將所需的預設值包裝在可呼叫物件中。例如,如果您想要為 JSONField 指定預設的 dict,請使用函式

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


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

lambda 不能用於像 default 這樣的欄位選項,因為它們無法被遷移序列化。請參閱該文件以了解其他注意事項。

對於像 ForeignKey 這樣對應到模型實例的欄位,預設值應該是它們所參考欄位的值(pk,除非設定了 to_field),而不是模型實例。

當建立新的模型實例,且未為欄位提供值時,會使用預設值。當欄位為主索引鍵時,如果欄位設定為 None,也會使用預設值。

也可以使用 Field.db_default 在資料庫層級設定預設值。

editable

Field.editable

如果為 False,則該欄位不會顯示在管理介面或任何其他ModelForm中。它們也會在模型驗證期間被跳過。預設值為 True

error_messages

Field.error_messages[原始碼]

error_messages 參數可讓您覆寫欄位將會引發的預設訊息。傳入一個字典,其鍵與您想要覆寫的錯誤訊息相符。

錯誤訊息的鍵包括 nullblankinvalidinvalid_choiceuniqueunique_for_date。以下 欄位類型 部分中會為每個欄位指定其他錯誤訊息的鍵。

這些錯誤訊息通常不會傳播到表單。請參閱關於模型錯誤訊息的考量

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 會自動新增一個欄位來保存主索引鍵,因此除非您想要覆寫預設的主索引鍵行為,否則您不需要在任何欄位上設定 primary_key=True。可以在 AppConfig.default_auto_field 中依應用程式指定自動建立的主索引鍵欄位的類型,或在 DEFAULT_AUTO_FIELD 設定中全域指定。如需更多資訊,請參閱自動主索引鍵欄位

primary_key=True 表示 null=Falseunique=True。一個物件上只允許有一個主索引鍵。

主索引鍵欄位是唯讀的。如果您變更現有物件上的主索引鍵的值,然後儲存它,則會建立一個新物件,與舊物件並存。

刪除物件時,主索引鍵欄位會設定為 None

unique

Field.unique[原始碼]

如果為 True,則此欄位在整個表格中必須是唯一的。

這是由資料庫層級和模型驗證所強制執行的。如果您嘗試在 unique 欄位中儲存具有重複值的模型,則模型的 save() 方法會引發 django.db.IntegrityError

除了 ManyToManyFieldOneToOneField 之外,此選項在所有欄位類型上都有效。

請注意,當 uniqueTrue 時,您不需要指定 db_index,因為 unique 表示建立索引。

unique_for_date

Field.unique_for_date

將此設定為 DateFieldDateTimeField 的名稱,以要求此欄位對於日期欄位的值是唯一的。

例如,如果您有一個 title 欄位具有 unique_for_date="pub_date",那麼 Django 將不允許輸入兩個具有相同 titlepub_date 的記錄。

請注意,如果您將此設定指向 DateTimeField,則只會考慮欄位的日期部分。此外,當 USE_TZTrue 時,檢查將在物件儲存時的目前時區中執行。

這是由 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_dateunique_for_month 類似。

verbose_name

Field.verbose_name

欄位的人性化名稱。如果未給定 verbose name,Django 會使用欄位的屬性名稱自動建立它,並將底線轉換為空格。請參閱詳細欄位名稱

validators

Field.validators[原始碼]

要為此欄位執行的驗證器列表。請參閱驗證器文件以取得更多資訊。

欄位類型

AutoField

class AutoField(**options)[原始碼]

一個 IntegerField,會根據可用的 ID 自動遞增。您通常不需要直接使用它;如果您沒有另外指定,主要索引鍵欄位將會自動新增到您的模型中。請參閱自動主要索引鍵欄位

BigAutoField

class BigAutoField(**options)[原始碼]

一個 64 位元的整數,與 AutoField 非常相似,但保證可以容納從 19223372036854775807 的數字。

BigIntegerField

class BigIntegerField(**options)[原始碼]

一個 64 位元的整數,與 IntegerField 非常相似,但保證可以容納從 -92233720368547758089223372036854775807 的數字。此欄位的預設表單小工具是 NumberInput

BinaryField

class BinaryField(max_length=None, **options)[原始碼]

一個用於儲存原始二進位資料的欄位。它可以被賦予 bytesbytearraymemoryview

預設情況下,BinaryField 會將 editable 設定為 False,在這種情況下,它不能包含在 ModelForm 中。

BinaryField.max_length

可選。欄位的最大長度(以位元組為單位)。最大長度會使用 MaxLengthValidator 在 Django 的驗證中強制執行。

濫用 BinaryField

儘管您可能會考慮將檔案儲存在資料庫中,但請考慮這在 99% 的情況下是糟糕的設計。此欄位不能取代適當的 靜態檔案 處理。

BooleanField

class BooleanField(**options)[原始碼]

一個 true/false 欄位。

此欄位的預設表單小工具是 CheckboxInput,如果 null=True 則是 NullBooleanSelect

當未定義 Field.default 時,BooleanField 的預設值為 None

CharField

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

字串欄位,適用於小型到大型的字串。

對於大量的文字,請使用 TextField

此欄位的預設表單小工具是 TextInput

CharField 具有以下額外參數:

CharField.max_length

欄位的最大長度(以字元為單位)。max_length 在資料庫層級和 Django 的驗證中,會使用 MaxLengthValidator 強制執行。對於 Django 包含的所有資料庫後端,除了支援無限制 VARCHAR 欄位的 PostgreSQL 之外,這都是必需的。

注意

如果您正在編寫必須可移植到多個資料庫後端的應用程式,您應該了解某些後端的 max_length 存在限制。有關詳細資訊,請參閱資料庫後端說明

CharField.db_collation

選用。欄位的資料庫定序名稱。

注意

定序名稱並未標準化。因此,這將無法在多個資料庫後端之間移植。

Oracle

只有在 MAX_STRING_SIZE 資料庫初始化參數設定為 EXTENDED 時,Oracle 才支援定序。

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

此欄位的預設表單小工具是 DateInput。管理介面會新增一個 JavaScript 日曆和「今天」的快捷方式。包含額外的 invalid_date 錯誤訊息鍵。

選項 auto_now_addauto_nowdefault 互斥。這些選項的任何組合都會導致錯誤。

注意

按照目前的實作方式,將 auto_nowauto_now_add 設定為 True 會導致欄位設定為 editable=Falseblank=True

注意

auto_nowauto_now_add 選項在建立或更新時,將始終使用預設時區中的日期。如果您需要不同的設定,您可能需要考慮使用自己的可呼叫預設值,或覆寫 save(),而不是使用 auto_nowauto_now_add;或者使用 DateTimeField 而不是 DateField,並決定如何在顯示時處理從日期時間到日期的轉換。

警告

始終將 DateFielddatetime.date 實例一起使用。

如果您有 datetime.datetime 實例,建議您先將其轉換為 datetime.date。如果您不這樣做,DateField 會將 datetime.datetime 本地化到預設時區,並將其轉換為 datetime.date 實例,從而移除其時間元件。這對於儲存和比較都是如此。

DateTimeField

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

以 Python 的 datetime.datetime 實例表示的日期和時間。採用與 DateField 相同的額外參數。

此欄位的預設表單小工具是單個 DateTimeInput。管理介面使用兩個單獨的 TextInput 小工具,並附帶 JavaScript 快捷方式。

警告

始終將 DateTimeFielddatetime.datetime 實例一起使用。

如果您有一個 datetime.date 的實例,建議您先將其轉換為 datetime.datetime。如果您不這麼做,DateTimeField 將會使用 預設時區 中的午夜時間作為時間部分。這在儲存和比較時皆是如此。若要將 DateTimeField 的日期部分與 datetime.date 的實例進行比較,請使用 date 查詢。

DecimalField

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

一個固定精度的十進位數字,在 Python 中以 Decimal 的實例表示。它會使用 DecimalValidator 驗證輸入。

具有以下必要參數:

DecimalField.max_digits

數字中允許的最大位數。請注意,此數字必須大於或等於 decimal_places

DecimalField.decimal_places

要儲存的數字的小數位數。

例如,要儲存解析度為 2 位小數、最大值為 999.99 的數字,您會使用:

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

而要儲存解析度為 10 位小數、最大值約為 10 億的數字,則會使用:

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

localizeFalse 時,此欄位的預設表單小部件是 NumberInput,否則為 TextInput

注意

有關 FloatFieldDecimalField 類別之間差異的更多資訊,請參閱 FloatField vs. DecimalField。您還應該注意十進位欄位的 SQLite 限制

DurationField

class DurationField(**options)[原始碼]

一個用於儲存時間段的欄位 - 在 Python 中以 timedelta 建模。在 PostgreSQL 上使用時,使用的資料類型為 interval,而在 Oracle 上,資料類型為 INTERVAL DAY(9) TO SECOND(6)。否則,會使用微秒的 bigint

注意

DurationField 的算術運算在大多數情況下都有效。然而,在 PostgreSQL 以外的所有資料庫上,將 DurationField 的值與 DateTimeField 實例的算術運算進行比較時,結果不如預期。

EmailField

class EmailField(max_length=254, **options)[原始碼]

一個 CharField,使用 EmailValidator 檢查該值是否為有效的電子郵件地址。

FileField

class FileField(upload_to='', storage=None, max_length=100, **options)[原始碼]

一個檔案上傳欄位。

注意

不支援 primary_key 參數,如果使用將會引發錯誤。

具有以下可選參數:

FileField.upload_to

此屬性提供了一種設定上傳目錄和檔案名稱的方式,並且可以透過兩種方式設定。在這兩種情況下,該值都會傳遞給 Storage.save() 方法。

如果您指定一個字串值或一個 Path,它可以包含 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)
FileField.storage

一個儲存物件,或是一個會回傳儲存物件的可呼叫物件。此物件處理檔案的儲存與檢索。關於如何提供此物件的詳細資訊,請參閱管理檔案

此欄位的預設表單小工具是 ClearableFileInput

在模型中使用 FileFieldImageField(見下文)需要幾個步驟:

  1. 在您的設定檔中,您需要定義 MEDIA_ROOT 作為您希望 Django 儲存上傳檔案的完整路徑。(為了效能考量,這些檔案不會儲存在資料庫中。)定義 MEDIA_URL 作為該目錄的基本公開 URL。請確保此目錄可由網頁伺服器的使用者帳戶寫入。

  2. FileFieldImageField 新增至您的模型,並定義 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' 是兩位數的月份,而 '%d' 是兩位數的日期。如果您在 2007 年 1 月 15 日上傳檔案,它將會儲存在 /home/media/photos/2007/01/15 目錄中。

如果您想要檢索已上傳檔案的磁碟檔案名稱或檔案大小,您可以使用 namesize 屬性;有關可用屬性和方法的更多資訊,請參閱 File 類別參考和管理檔案主題指南。

注意

檔案是在資料庫中儲存模型的一部分時儲存的,因此在模型儲存之前,無法依賴磁碟上使用的實際檔案名稱。

可以使用 url 屬性取得已上傳檔案的相對 URL。在內部,它會呼叫基礎 Storage 類別的 url() 方法。

請注意,無論何時處理上傳的檔案,您都應密切注意您上傳檔案的位置以及檔案的類型,以避免安全漏洞。驗證所有上傳的檔案,以確保檔案是您認為的檔案。例如,如果您盲目地讓某人將檔案上傳到您網頁伺服器文件根目錄中的目錄,而未經驗證,那麼某人可能會上傳 CGI 或 PHP 腳本,並透過訪問您網站上的 URL 來執行該腳本。請勿允許這種情況發生。

另請注意,即使上傳的 HTML 檔案,由於它可以由瀏覽器(而不是伺服器)執行,也可能構成等同於 XSS 或 CSRF 攻擊的安全威脅。

FileField 實例會在您的資料庫中建立為 varchar 欄位,預設最大長度為 100 個字元。與其他欄位一樣,您可以使用 max_length 引數來變更最大長度。

FileFieldFieldFile

class FieldFile[原始碼]

當您存取模型上的 FileField 時,您會獲得 FieldFile 的實例,作為存取底層檔案的代理。

FieldFile 的 API 與 File 的 API 相仿,但有一個關鍵差異:此類別所包裝的物件不一定是 Python 內建檔案物件的包裝。相反地,它是 Storage.open() 方法結果的包裝,它可能是 File 物件,或者可能是自訂儲存裝置的 File API 實作。

除了從 File 繼承的 API(例如 read()write())之外,FieldFile 還包含幾個可用於與底層檔案互動的方法。

警告

此類別的兩個方法 save()delete() 預設會將相關聯的 FieldFile 的模型物件儲存在資料庫中。

FieldFile.name

檔案的名稱,包含相關聯的 FileFieldStorage 根目錄的相對路徑。

FieldFile.path[原始碼]

一個唯讀屬性,用於透過呼叫底層 path() 方法來存取檔案的本機檔案系統路徑。該方法屬於 Storage 類別。

FieldFile.size[原始碼]

底層 Storage.size() 方法的結果。

FieldFile.url[原始碼]

一個唯讀屬性,用於透過呼叫底層 url() 方法來存取檔案的相對 URL。該方法屬於 Storage 類別。

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='', match=None, recursive=False, allow_files=True, allow_folders=False, max_length=100, **options)[原始碼]

一個 CharField,其選項僅限於檔案系統上特定目錄中的檔案名稱。有一些特殊的參數,其中第一個參數是必要的。

FilePathField.path

必要參數。此 FilePathField 應從中取得其選項的目錄的絕對檔案系統路徑。範例: "/home/images"

path 也可以是可呼叫的,例如在執行時動態設定路徑的函式。範例:

import os
from django.conf import settings
from django.db import models


def images_path():
    return os.path.join(settings.LOCAL_FILE_DIR, "images")


class MyModel(models.Model):
    file = models.FilePathField(path=images_path)
FilePathField.match

可選參數。一個正規表示式,以字串形式表示,FilePathField 將使用它來過濾檔案名稱。請注意,正規表示式將應用於基本檔案名稱,而不是完整路徑。範例: "foo.*\.txt$",這將會匹配名為 foo23.txt 的檔案,但不會匹配 bar.txtfoo23.png

FilePathField.recursive

可選參數。可以是 TrueFalse。預設值為 False。指定是否應包含 path 的所有子目錄。

FilePathField.allow_files

可選參數。可以是 TrueFalse。預設值為 True。指定是否應包含指定位置的檔案。必須將此項或 allow_folders 設定為 True

FilePathField.allow_folders

可選參數。可以是 TrueFalse。預設值為 False。指定是否應包含指定位置的資料夾。必須將此項或 allow_files 設定為 True

一個潛在的陷阱是 match 應用於基本檔案名稱,而不是完整路徑。所以,這個例子:

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

…會匹配 /home/images/foo.png,但不會匹配 /home/images/foo/bar.png,因為 match 適用於基本檔名(foo.pngbar.png)。

FilePathField 實例會在您的資料庫中建立為 varchar 欄位,預設最大長度為 100 個字元。與其他欄位一樣,您可以使用 max_length 引數變更最大長度。

FloatField

class FloatField(**options)[原始碼]

一個浮點數,在 Python 中以 float 實例表示。

localizeFalse 時,此欄位的預設表單小部件是 NumberInput,否則為 TextInput

FloatField vs. DecimalField

FloatField 類別有時會與 DecimalField 類別混淆。雖然它們都表示實數,但它們表示這些數字的方式不同。FloatField 在內部使用 Python 的 float 型別,而 DecimalField 則使用 Python 的 Decimal 型別。有關兩者之間差異的資訊,請參閱 Python 的 decimal 模組的文件。

GeneratedField

Django 5.0 的新功能。
class GeneratedField(expression, output_field, db_persist=None, **kwargs)[原始碼]

一個欄位,其值始終根據模型中的其他欄位計算得出。此欄位由資料庫本身管理和更新。使用 GENERATED ALWAYS SQL 語法。

產生欄位有兩種:儲存型和虛擬型。儲存型產生欄位會在寫入(插入或更新)時計算,並佔用儲存空間,就像它是常規欄位一樣。虛擬型產生欄位不佔用儲存空間,並在讀取時計算。因此,虛擬型產生欄位類似於視圖,而儲存型產生欄位則類似於實體化視圖。

GeneratedField.expression

資料庫使用的一個 Expression,以便在每次變更模型時自動設定欄位值。

表示式應具有確定性,且僅參考模型內的欄位(在同一資料庫表格中)。產生欄位不能參考其他產生欄位。資料庫後端可能會施加其他限制。

GeneratedField.output_field

一個模型欄位實例,用於定義欄位的資料型別。

GeneratedField.db_persist

決定資料庫欄位是否應像真實欄位一樣佔用儲存空間。如果 False,則該欄位會充當虛擬欄位,且不佔用資料庫儲存空間。

PostgreSQL 僅支援持續性欄位。Oracle 僅支援虛擬欄位。

重新整理資料

由於資料庫總是計算值,因此在 save() 之後,必須重新載入物件以存取新值,例如,使用 refresh_from_db()

資料庫限制

關於產生欄位,有許多特定於資料庫的限制,Django 不會驗證這些限制,並且資料庫可能會引發錯誤,例如,PostgreSQL 要求產生欄位中引用的函數和運算子標記為 IMMUTABLE

您應始終檢查您的資料庫是否支援 expression。請查看 MariaDBMySQLOraclePostgreSQLSQLite 文件。

GenericIPAddressField

class GenericIPAddressField(protocol='both', unpack_ipv4=False, **options)[原始碼]

一個 IPv4 或 IPv6 位址,採用字串格式(例如 192.0.2.302a02:42fe::4)。此欄位的預設表單小工具是 TextInput

IPv6 位址正規化遵循 RFC 4291 第 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

解壓縮類似 ::ffff:192.0.2.1 的 IPv4 對應位址。如果啟用此選項,則該位址將解壓縮為 192.0.2.1。預設為停用。僅當 protocol 設定為 'both' 時才能使用。

如果您允許空白值,則必須允許 Null 值,因為空白值會儲存為 Null。

ImageField

class ImageField(upload_to=None, height_field=None, width_field=None, max_length=100, **options)[原始碼]

繼承 FileField 的所有屬性和方法,但也驗證上傳的物件是否為有效的影像。

除了 FileField 可用的特殊屬性外,ImageField 還具有 heightwidth 屬性。

為了方便查詢這些屬性,ImageField 具有以下可選參數:

ImageField.height_field

一個模型欄位的名稱,每次設定圖片物件時,會自動填入圖片的高度。

ImageField.width_field

一個模型欄位的名稱,每次設定圖片物件時,會自動填入圖片的寬度。

需要 pillow 函式庫。

ImageField 實例在您的資料庫中會建立為 varchar 欄位,預設最大長度為 100 個字元。如同其他欄位,您可以使用 max_length 參數來變更最大長度。

此欄位的預設表單小工具是 ClearableFileInput

IntegerField

class IntegerField(**options)[原始碼]

一個整數。在 Django 支援的所有資料庫中,從 -21474836482147483647 的值都是安全的。

它使用 MinValueValidatorMaxValueValidator,根據預設資料庫支援的值來驗證輸入。

localizeFalse 時,此欄位的預設表單小部件是 NumberInput,否則為 TextInput

JSONField

class JSONField(encoder=None, decoder=None, **options)[原始碼]

一個用於儲存 JSON 編碼資料的欄位。在 Python 中,資料以其 Python 原生格式表示:字典、列表、字串、數字、布林值和 None

MariaDB、MySQL、Oracle、PostgreSQL 和 SQLite(啟用 JSON1 擴充功能)支援 JSONField

JSONField.encoder

一個可選的 json.JSONEncoder 子類別,用於序列化標準 JSON 序列化器不支援的資料類型(例如 datetime.datetimeUUID)。例如,您可以使用 DjangoJSONEncoder 類別。

預設值為 json.JSONEncoder

JSONField.decoder

一個可選的 json.JSONDecoder 子類別,用於反序列化從資料庫檢索的值。該值將採用自訂編碼器選擇的格式(通常是字串)。您的反序列化可能需要考慮到您無法確定輸入類型的事實。例如,您可能會返回一個實際上是字串的 datetime,而該字串恰好採用了為 datetime 選擇的相同格式。

預設值為 json.JSONDecoder

若要在資料庫中查詢 JSONField,請參閱 查詢 JSONField

預設值

如果您為欄位提供 default,請確保它是可呼叫的,例如 dict 類別或每次都返回新物件的函式。錯誤地使用可變物件(如 default={}default=[])會建立一個在所有實例之間共享的可變預設值。

索引

IndexField.db_index 都會建立 B 樹索引,這在查詢 JSONField 時並不是很實用。只有在 PostgreSQL 上,您可以使用更適合的 GinIndex

PostgreSQL 使用者

PostgreSQL 有兩種原生 JSON 型資料類型:jsonjsonb。它們之間的主要區別在於它們的儲存方式以及查詢方式。PostgreSQL 的 json 欄位會儲存為 JSON 的原始字串表示形式,並且在根據索引鍵查詢時必須即時解碼。jsonb 欄位則會根據 JSON 的實際結構儲存,這允許建立索引。取捨是寫入 jsonb 欄位的成本略高。JSONField 使用 jsonb

Oracle 使用者

Oracle 資料庫不支援儲存 JSON 純量值。僅支援 JSON 物件和陣列(在 Python 中使用 dictlist 表示)。

PositiveBigIntegerField

class PositiveBigIntegerField(**options)[原始碼]

類似於 PositiveIntegerField,但僅允許小於特定(資料庫相關)點的值。在 Django 支援的所有資料庫中,從 09223372036854775807 的值都是安全的。

PositiveIntegerField

class PositiveIntegerField(**options)[原始碼]

類似於 IntegerField,但必須為正數或零 (0)。在 Django 支援的所有資料庫中,從 02147483647 的值都是安全的。為了向後相容,接受值 0

PositiveSmallIntegerField

class PositiveSmallIntegerField(**options)[原始碼]

類似於 PositiveIntegerField,但僅允許小於特定(資料庫相關)點的值。在 Django 支援的所有資料庫中,從 032767 的值都是安全的。

SlugField

class SlugField(max_length=50, **options)[原始碼]

Slug 是一個報紙術語。Slug 是某事物的簡短標籤,僅包含字母、數字、底線或連字號。它們通常用於 URL 中。

如同 CharField,您可以指定 max_length(請閱讀關於資料庫可攜性和該章節中關於 max_length 的說明)。如果沒有指定 max_length,Django 將使用預設長度 50。

表示設定 Field.db_indexTrue

通常,根據其他值自動預先填入 SlugField 會很有用。您可以使用 prepopulated_fields 在管理介面中自動執行此操作。

它使用 validate_slugvalidate_unicode_slug 進行驗證。

SlugField.allow_unicode

如果 True,則該欄位除了接受 ASCII 字母外,還接受 Unicode 字母。預設值為 False

SmallAutoField

class SmallAutoField(**options)[原始碼]

類似於 AutoField,但僅允許低於特定(與資料庫相關)限制的值。在 Django 支援的所有資料庫中,從 132767 的值都是安全的。

SmallIntegerField

class SmallIntegerField(**options)[原始碼]

類似於 IntegerField,但僅允許低於特定(與資料庫相關)點的值。在 Django 支援的所有資料庫中,從 -3276832767 的值都是安全的。

TextField

class TextField(**options)[原始碼]

一個大型文字欄位。此欄位的預設表單 Widget 是一個 Textarea

如果您指定 max_length 屬性,它將反映在自動產生的表單欄位的 Textarea Widget 中。但是,它不會在模型或資料庫層級強制執行。請使用 CharField 來實現此目的。

TextField.db_collation

選用。欄位的資料庫定序名稱。

注意

定序名稱並未標準化。因此,這將無法在多個資料庫後端之間移植。

Oracle

Oracle 不支援 TextField 的排序規則。

TimeField

class TimeField(auto_now=False, auto_now_add=False, **options)[原始碼]

以 Python 的 datetime.time 實例表示的時間。接受與 DateField 相同的自動填入選項。

此欄位的預設表單 Widget 是一個 TimeInput。管理介面會加入一些 JavaScript 快捷方式。

URLField

class URLField(max_length=200, **options)[原始碼]

用於 URL 的 CharField,由 URLValidator 驗證。

此欄位的預設表單 Widget 是一個 URLInput

如同所有 CharField 子類別,URLField 接受可選的 max_length 引數。如果您沒有指定 max_length,則會使用預設值 200。

UUIDField

class UUIDField(**options)[原始碼]

用於儲存通用唯一識別碼的欄位。使用 Python 的 UUID 類別。當在 PostgreSQL 和 MariaDB 10.7+ 上使用時,會儲存在 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 的實例。

在 PostgreSQL 和 MariaDB 10.7+ 上的查詢

在 PostgreSQL 上使用 iexactcontainsicontainsstartswithistartswithendswithiendswith 查詢時,如果值不包含連字符,則會失效,因為 PostgreSQL 和 MariaDB 10.7+ 將它們儲存在帶有連字符的 uuid 數據類型中。

關聯欄位

Django 也定義了一組表示關聯的欄位。

ForeignKey

class ForeignKey(to, on_delete, **options)[原始碼]

一個多對一的關聯。需要兩個位置引數:模型關聯的類別以及 on_delete 選項。

from django.db import models


class Manufacturer(models.Model):
    name = models.TextField()


class Car(models.Model):
    manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)

第一個位置引數可以是具體的模型類別,或是模型類別的延遲參考遞迴關聯,其中一個模型與自身有關係,也受到支援。

關於第二個位置引數的詳細資訊,請參閱ForeignKey.on_delete

資料庫索引會自動在 ForeignKey 上建立。您可以將db_index 設定為 False 來停用此功能。如果您建立外部索引鍵是為了保持一致性,而不是為了聯結,或者您將建立替代索引(例如部分索引或多欄索引),您可能希望避免索引的額外開銷。

資料庫表示法

在幕後,Django 會在欄位名稱後附加 "_id" 來建立其資料庫欄位名稱。在上面的範例中,Car 模型的資料庫表格將會有一個 manufacturer_id 欄位。您可以透過指定 db_column 來明確地變更此設定,但是您的程式碼永遠不應該處理資料庫欄位名稱(除非您撰寫自訂 SQL)。您將始終處理您的模型物件的欄位名稱。

引數

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[原始碼]

    透過引發 ProtectedErrordjango.db.IntegrityError 的子類別)來防止刪除參考的物件。

  • RESTRICT[原始碼]

    透過引發 RestrictedErrordjango.db.IntegrityError 的子類別)來防止刪除參考的物件。不同於 PROTECT,如果參考的物件也透過 CASCADE 關係參考同一個操作中正在刪除的不同物件,則允許刪除該參考的物件。

    請考慮以下模型集

    class Artist(models.Model):
        name = models.CharField(max_length=10)
    
    
    class Album(models.Model):
        artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
    
    
    class Song(models.Model):
        artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
        album = models.ForeignKey(Album, on_delete=models.RESTRICT)
    

    即使這意味著刪除 Song 所參考的 Album,也可以刪除 Artist,因為 Song 也透過聯級關係參考 Artist 本身。例如

    >>> artist_one = Artist.objects.create(name="artist one")
    >>> artist_two = Artist.objects.create(name="artist two")
    >>> album_one = Album.objects.create(artist=artist_one)
    >>> album_two = Album.objects.create(artist=artist_two)
    >>> song_one = Song.objects.create(artist=artist_one, album=album_one)
    >>> song_two = Song.objects.create(artist=artist_one, album=album_two)
    >>> album_one.delete()
    # Raises RestrictedError.
    >>> artist_two.delete()
    # Raises RestrictedError.
    >>> artist_one.delete()
    (4, {'Song': 2, 'Album': 1, 'Artist': 1})
    
  • SET_NULL[原始碼]

    ForeignKey 設定為 null;只有在 nullTrue 時才有可能。

  • SET_DEFAULT[原始碼]

    ForeignKey 設定為其預設值;必須為 ForeignKey 設定預設值。

  • 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 或管理介面呈現此欄位時,設定此欄位可用選項的限制(預設情況下,查詢集中的所有物件都可供選擇)。可以使用字典、Q 物件,或傳回字典或 Q 物件的可呼叫對象。

例如:

staff_member = models.ForeignKey(
    User,
    on_delete=models.CASCADE,
    limit_choices_to={"is_staff": True},
)

會導致 ModelForm 上對應的欄位僅列出具有 is_staff=TrueUsers。這在 Django 管理介面中可能很有用。

可呼叫的形式可能很有用,例如,當與 Python datetime 模組結合使用時,可以按日期範圍限制選擇。例如

def limit_pub_date_choices():
    return {"pub_date__lte": datetime.date.today()}


limit_choices_to = limit_pub_date_choices

如果 limit_choices_to 是或傳回一個 Q 物件,這對於複雜查詢很有用,那麼只有當該欄位未在模型的 ModelAdmin 中的 raw_id_fields 中列出時,它才會影響管理介面中可用的選項。

注意

如果將可呼叫對象用於 limit_choices_to,則每次實例化新表單時都會調用它。在驗證模型時(例如透過管理命令或管理介面)也可能會調用它。管理介面會多次構建查詢集,以在各種邊緣情況下驗證其表單輸入,因此您的可呼叫對象可能會被調用多次。

ForeignKey.related_name

從關聯物件返回到此物件的關係所使用的名稱。它也是 related_query_name(從目標模型使用反向篩選器名稱的名稱)的預設值。有關完整說明和範例,請參閱關聯物件文件。請注意,在定義 抽象模型上的關係時,您必須設定此值;並且當您這樣做時,可以使用一些特殊語法

如果您希望 Django 不建立反向關係,請將 related_name 設定為 '+' 或以 '+' 結尾。例如,這將確保 User 模型不會與此模型有反向關係

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

從目標模型使用反向篩選器名稱的名稱。如果設定了,則預設為 related_namedefault_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 透過一些特殊語法支援應用程式標籤和類別內插。

ForeignKey.to_field

關係指向的關聯物件上的欄位。預設情況下,Django 使用關聯物件的主鍵。如果您參考不同的欄位,該欄位必須具有 unique=True

ForeignKey.db_constraint

控制是否應在資料庫中為此外鍵建立約束。預設值為 True,這幾乎可以肯定是您想要的;將此設定為 False 可能會對資料完整性造成非常不利的影響。也就是說,以下是一些您可能想要這樣做的情況

  • 您有不有效的舊資料。

  • 您正在對資料庫進行分片。

如果將此設定為 False,則存取不存在的關聯物件會引發其 DoesNotExist 例外狀況。

ForeignKey.swappable

如果此 ForeignKey 指向可交換模型,則控制移轉框架的反應。如果它是 True(預設值),那麼如果 ForeignKey 指向的模型與 settings.AUTH_USER_MODEL 的目前值(或其他可交換模型設定)相符,則該關係將使用對設定的參考儲存在移轉中,而不是直接對模型的參考。

只有當您確定您的模型應始終指向交換進來的模型時,才需要將此覆寫為 False - 例如,如果它是專為您的自訂使用者模型設計的設定檔模型。

將其設定為 False 並不意味著即使可交換模型被換出,您也可以參考它 - False 表示使用此外鍵進行的移轉將始終參考您指定的確切模型(因此,如果使用者嘗試使用您不支援的使用者模型執行,則會硬性失敗)。

如果有疑問,請將其保留為預設值 True

ManyToManyField

class ManyToManyField(to, **options)[原始碼]

多對多關係。需要一個位置引數:模型關聯的類別,其工作方式與 ForeignKey 完全相同,包括遞迴延遲關係。

可以使用欄位的 RelatedManager 新增、移除或建立關聯物件。

資料庫表示法

在幕後,Django 會建立一個中間聯結表來表示多對多關係。預設情況下,此資料表名稱是使用多對多欄位的名稱和包含該欄位的模型的資料表名稱產生的。由於某些資料庫不支援超過特定長度的資料表名稱,因此這些資料表名稱會自動截斷,並使用唯一性雜湊,例如 author_books_9cdf。您可以使用 db_table 選項手動提供聯結表的名稱。

引數

ManyToManyField 接受一組額外的參數(全部為選填),這些參數控制關聯的運作方式。

ManyToManyField.related_name

ForeignKey.related_name 相同。

ManyToManyField.related_query_name

ForeignKey.related_query_name 相同。

ManyToManyField.limit_choices_to

ForeignKey.limit_choices_to 相同。

ManyToManyField.symmetrical

僅用於在自身上定義 ManyToManyFields。考慮以下模型

from django.db import models


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

當 Django 處理此模型時,它會識別出它自身有一個 ManyToManyField,因此,它不會將 person_set 屬性新增至 Person 類別。相反地,ManyToManyField 會被假定為對稱的 – 也就是說,如果我是你的朋友,那麼你也是我的朋友。

如果您不希望與 self 的多對多關係是對稱的,請將 symmetrical 設定為 False。這會強制 Django 新增反向關係的描述符,允許 ManyToManyField 關係為非對稱的。

ManyToManyField.through

Django 會自動產生一個資料表來管理多對多關係。但是,如果您想要手動指定中介資料表,可以使用 through 選項來指定您想要使用的代表中介資料表的 Django 模型。

此選項最常見的用途是當您想要將額外資料與多對多關係關聯時。

注意

如果您不希望在相同的實例之間有多個關聯,請新增一個 UniqueConstraint,其中包含來源和目標欄位。Django 自動產生的多對多資料表包含此類約束。

注意

使用中介模型的遞迴關係無法確定反向存取器的名稱,因為它們會相同。您至少需要為其中一個設定 related_name。如果您希望 Django 不建立反向關聯,請將 related_name 設定為 '+'

如果您沒有指定明確的 through 模型,仍然有一個隱含的 through 模型類別,您可以使用它來直接存取為保存關聯而建立的資料表。它有三個欄位來連結模型。

如果來源模型和目標模型不同,則會產生下列欄位

  • id:關聯的主鍵。

  • <containing_model>_id:宣告 ManyToManyField 的模型的 id

  • <other_model>_idManyToManyField 指向的模型的 id

如果 ManyToManyField 從相同模型指向自身,則會產生下列欄位

  • id:關聯的主鍵。

  • from_<model>_id:指向模型的實例的 id(即來源實例)。

  • to_<model>_id:關係指向的實例的 id(即目標模型實例)。

這個類別可以用來查詢給定模型實例的關聯記錄,就像一般的模型一樣

Model.m2mfield.through.objects.all()
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 是指向定義 ManyToManyField 的模型的外鍵名稱(在此案例中為 group),而 field2 是指向目標模型的外鍵名稱(在此案例中為 person)。

當您在中介模型上有多個指向參與多對多關係的任何(甚至兩個)模型的外鍵時,您必須指定 through_fields。當使用中介模型時,並且有兩個以上指向模型的外鍵,或者您想要明確指定 Django 應使用哪兩個時,這也適用於遞迴關係

ManyToManyField.db_table

用於儲存多對多資料的資料表的名稱。如果未提供此名稱,Django 會根據以下名稱假設一個預設名稱:定義關係的模型資料表和欄位本身的名稱。

ManyToManyField.db_constraint

控制是否應在資料庫中為中介資料表中的外鍵建立約束。預設值為 True,這幾乎可以肯定是您想要的;將此值設定為 False 可能會對資料完整性造成非常不利的影響。也就是說,以下是一些您可能想要這樣做的情況

  • 您有不有效的舊資料。

  • 您正在對資料庫進行分片。

同時傳遞 db_constraintthrough 是一個錯誤。

ManyToManyField.swappable

如果此 ManyToManyField 指向可替換模型,則控制移轉架構的反應。如果它是 True(預設值),則如果 ManyToManyField 指向與 settings.AUTH_USER_MODEL 的目前值(或其他可替換的模型設定)相符的模型,則關係將使用對設定的引用而不是直接對模型的引用儲存在移轉中。

只有當您確定您的模型應始終指向交換進來的模型時,才需要將此覆寫為 False - 例如,如果它是專為您的自訂使用者模型設計的設定檔模型。

如果有疑問,請將其保留為預設值 True

ManyToManyField 不支援 validators

null 沒有效果,因為在資料庫層級沒有辦法要求關聯性。

OneToOneField

class OneToOneField(to, on_delete, parent_link=False, **options)[原始碼]

一對一關係。概念上,這與具有 unique=TrueForeignKey 相似,但關係的「反向」端將直接返回單個物件。

這最常用於以某種方式「擴展」另一個模型之模型的主鍵;例如,多表繼承 是通過從子模型到父模型添加隱式的一對一關係來實現的。

需要一個位置引數:模型將與之關聯的類別。這與 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

當存取相關表格中不存在條目的反向關係時,會引發 RelatedObjectDoesNotExist 例外。這是目標模型的 Model.DoesNotExist 例外的子類別,並且可以作為反向存取器的屬性存取。例如,如果使用者沒有由 MySpecialUser 指定的主管

try:
    user.supervisor_of
except User.supervisor_of.RelatedObjectDoesNotExist:
    pass

此外,OneToOneField 接受 ForeignKey 接受的所有額外引數,再加上一個額外的引數

當在繼承自另一個 具體模型 的模型中使用時,如果 True,則表示該欄位應被用作回溯到父類別的連結,而不是通常由子類別化隱式建立的額外 OneToOneField

有關 OneToOneField 的使用範例,請參閱 一對一關係

延遲關係

延遲關係允許通過名稱(作為字串)引用模型或建立遞迴關係。字串可以用作任何關係欄位中的第一個引數,以延遲引用模型。延遲參考可以是遞迴的相對的絕對的

遞迴

要定義模型引用自身的關係,請使用 "self" 作為關係欄位的第一個引數

from django.db import models


class Manufacturer(models.Model):
    name = models.TextField()
    suppliers = models.ManyToManyField("self", symmetrical=False)

當在 抽象模型 中使用時,遞迴關係會解析為每個具體子類別引用自身。

相對

當需要與尚未定義的模型建立關係時,可以使用其名稱而不是模型物件本身來引用它

from django.db import models


class Car(models.Model):
    manufacturer = models.ForeignKey(
        "Manufacturer",
        on_delete=models.CASCADE,
    )


class Manufacturer(models.Model):
    name = models.TextField()
    suppliers = models.ManyToManyField("self", symmetrical=False)

抽象模型 上以此方式定義的關係會在模型被子類別化為具體模型時解析,並且與抽象模型的 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):
    name = models.TextField()


class Car(AbstractCar):
    pass

在此範例中,Car.manufacturer 關係將解析為 production.Manufacturer,因為它指向在 production/models.py 檔案中定義的具體模型。

具有相對參考的可重複使用模型

相對參考允許建立具有關係的可重複使用抽象模型,這些關係可以解析為不同應用程式中各種子類別中被引用模型的不同實作。

絕對

絕對參考使用模型的 app_label 和類別名稱來指定模型,允許跨不同應用程式的模型參考。這種延遲關係類型還可以幫助解析循環導入。

例如,如果 Manufacturer 模型定義在另一個稱為 thirdpartyapp 的應用程式中,則可以將其引用為

class Car(models.Model):
    manufacturer = models.ForeignKey(
        "thirdpartyapp.Manufacturer",
        on_delete=models.CASCADE,
    )

絕對參考始終指向同一個模型,即使在 抽象模型 中使用時也是如此。

欄位 API 參考

class Field[原始碼]

Field 是一個抽象類別,表示資料庫表欄。Django 使用欄位來建立資料庫表 (db_type())、將 Python 類型對應到資料庫 (get_prep_value()) 以及反向對應 (from_db_value())。

因此,欄位是不同 Django API 中的基本部分,尤其是 模型查詢集

在模型中,欄位會作為類別屬性被例項化,並表示特定的表欄,請參閱 模型。它具有 nullunique 等屬性,以及 Django 用於將欄位值對應到資料庫特定值的方法。

FieldRegisterLookupMixin 的子類別,因此 TransformLookup 都可以註冊在其上,以便在 QuerySet 中使用(例如,field_name__exact="foo")。所有 內建查詢 預設都會註冊。

所有 Django 內建的欄位,例如 CharField,都是 Field 的特定實作。如果您需要自訂欄位,您可以繼承任何內建欄位,或是從頭開始撰寫一個 Field。無論哪種情況,請參閱如何建立自訂模型欄位

description

欄位的詳細描述,例如用於 django.contrib.admindocs 應用程式。

描述可以是以下形式

description = _("String (up to %(max_length)s)")

其中的引數會從欄位的 __dict__ 插入。

descriptor_class

一個實作 描述器協定 的類別,該類別會被實例化並指派給模型實例屬性。建構子必須接受單一引數,即 Field 實例。覆寫此類別屬性可自訂 get 和 set 行為。

為了將 Field 對應到資料庫特定的類型,Django 公開了幾個方法

get_internal_type()[原始碼]

返回一個字串,用於後端特定用途命名此欄位。預設情況下,它會返回類別名稱。

請參閱模擬內建欄位類型,以了解在自訂欄位中的用法。

db_type(connection)[原始碼]

返回 Field 的資料庫欄位資料類型,並考量到 connection

請參閱自訂資料庫類型,以了解在自訂欄位中的用法。

rel_db_type(connection)[原始碼]

返回指向 Field 的欄位(例如 ForeignKeyOneToOneField)的資料庫欄位資料類型,並考量到 connection

請參閱自訂資料庫類型,以了解在自訂欄位中的用法。

Django 需要與資料庫後端和欄位互動的三種主要情況

  • 當它查詢資料庫時(Python 值 -> 資料庫後端值)

  • 當它從資料庫載入資料時(資料庫後端值 -> Python 值)

  • 當它儲存到資料庫時(Python 值 -> 資料庫後端值)

在查詢時,會使用 get_db_prep_value()get_prep_value()

get_prep_value(value)[原始碼]

value 是模型屬性的目前值,此方法應傳回已準備好用作查詢中參數的格式資料。

請參閱將 Python 物件轉換為查詢值以了解用法。

get_db_prep_value(value, connection, prepared=False)[原始碼]

value 轉換為後端特定的值。預設情況下,如果 prepared=True,則返回 value,如果 False,則返回 get_prep_value()

請參閱將查詢值轉換為資料庫值以了解用法。

在載入資料時,會使用 from_db_value()

from_db_value(value, expression, connection)

將資料庫傳回的值轉換為 Python 物件。它是 get_prep_value() 的反向操作。

此方法不適用於大多數內建欄位,因為資料庫後端已經傳回正確的 Python 類型,或者後端本身會進行轉換。

expressionself 相同。

請參閱將值轉換為 Python 物件以了解用法。

注意

由於效能考量,對於不需要它的欄位(所有 Django 欄位),from_db_value 並未實作為無操作。因此,您可能無法在您的定義中呼叫 super

在儲存時,會使用 pre_save()get_db_prep_save()

get_db_prep_save(value, connection)[原始碼]

get_db_prep_value() 相同,但當欄位值必須儲存到資料庫時呼叫。預設情況下,會傳回 get_db_prep_value()

pre_save(model_instance, add)[原始碼]

get_db_prep_save() 之前呼叫的方法,用於準備要儲存的值(例如 DateField.auto_now)。

model_instance 是此欄位所屬的實例,而 add 表示該實例是否第一次儲存到資料庫。

它應傳回此欄位在 model_instance 中的適當屬性值。屬性名稱位於 self.attname 中(這是由 Field 設定的)。

請參閱在儲存之前預處理值以了解用法。

欄位通常會從序列化或表單等來源接收不同型別的值。

to_python(value)[來源]

將值轉換為正確的 Python 物件。它的作用與 value_to_string() 相反,並且也會在 clean() 中被呼叫。

請參閱將值轉換為 Python 物件以了解用法。

除了儲存至資料庫外,欄位也需要知道如何序列化其值

value_from_object(obj)[來源]

傳回指定模型實例的欄位值。

這個方法通常被 value_to_string() 使用。

value_to_string(obj)[來源]

obj 轉換為字串。用於序列化欄位的值。

請參閱 轉換欄位資料以進行序列化 以了解用法。

當使用 model 表單 時,Field 需要知道應該由哪個表單欄位來表示它

formfield(form_class=None, choices_form_class=None, **kwargs)[來源]

傳回這個欄位的預設 django.forms.Field,用於 ModelForm

預設情況下,如果 form_classchoices_form_class 都是 None,則它會使用 CharField。如果欄位有 choices 並且未指定 choices_form_class,則它會使用 TypedChoiceField

請參閱 為模型欄位指定表單欄位 以了解用法。

deconstruct()[來源]

傳回一個 4 元組,其中包含重新建立欄位所需的足夠資訊

  1. 模型上欄位的名稱。

  2. 欄位的匯入路徑(例如 "django.db.models.IntegerField")。這應該是最具移植性的版本,因此較不具體的可能更好。

  3. 位置引數的清單。

  4. 關鍵字引數的字典。

必須在 1.7 之前將這個方法新增至欄位,才能使用 遷移 遷移其資料。

註冊和擷取查詢

Field 實作 查詢註冊 API。此 API 可用於自訂哪些查詢可用於欄位類別及其例項,以及如何從欄位擷取查詢。

欄位屬性參考

每個 Field 實例都包含數個屬性,可讓您檢視其行為。當您需要撰寫依賴欄位功能的程式碼時,請使用這些屬性,而不是 isinstance 檢查。這些屬性可以與 Model._meta API 一起使用,以縮小搜尋特定欄位型別的範圍。自訂模型欄位應實作這些旗標。

欄位的屬性

Field.auto_created

布林旗標,指示欄位是否為自動建立,例如模型繼承使用的 OneToOneField

Field.concrete

布林旗標,指示欄位是否具有與其關聯的資料庫資料行。

Field.hidden

布林旗標,指示欄位是否為隱藏,且預設情況下不應由 Options.get_fields() 傳回。一個範例是以 '+' 開頭的 related_nameForeignKey 的反向欄位。

Field.is_relation

布林旗標,指示欄位的功能是否包含對一個或多個其他模型的參照(例如 ForeignKeyManyToManyFieldOneToOneField 等)。

Field.model

傳回定義欄位的模型。如果欄位定義在模型的超類別上,則 model 會參照超類別,而不是實例的類別。

具有關聯性的欄位屬性

這些屬性用於查詢關聯性的基數和其他詳細資訊。這些屬性存在於所有欄位上;但是,如果欄位是關聯性型別 ( Field.is_relation=True),則它們只會具有布林值(而不是 None)。

Field.many_to_many

布林旗標,如果欄位具有多對多關聯,則為 True;否則為 False。Django 中唯一包含此為 True 的欄位是 ManyToManyField

Field.many_to_one

布林旗標,如果欄位具有多對一關聯(例如 ForeignKey),則為 True;否則為 False

Field.one_to_many

布林旗標,如果欄位具有一對多關聯(例如 GenericRelationForeignKey 的反向),則為 True;否則為 False

Field.one_to_one

布林旗標,如果欄位具有一對一關聯(例如 OneToOneField),則為 True;否則為 False

Field.related_model

指向該欄位關聯的模型。例如,在 ForeignKey(Author, on_delete=models.CASCADE) 中的 AuthorGenericForeignKeyrelated_model 永遠是 None

返回頂部