模型 Meta 選項

此文件說明您可以在模型內部 class Meta 中提供的所有可能的元數據選項

可用的 Meta 選項

abstract

Options.abstract

如果 abstract = True,此模型將會是抽象基底類別

app_label

Options.app_label

如果模型是在 INSTALLED_APPS 中應用程式之外定義的,則必須宣告它屬於哪個應用程式

app_label = "myapp"

如果您想以 app_label.object_nameapp_label.model_name 的格式表示模型,您可以使用 model._meta.labelmodel._meta.label_lower 分別表示。

base_manager_name

Options.base_manager_name

管理員的屬性名稱,例如,'objects',用於模型的 _base_manager

db_table

Options.db_table

用於模型的資料庫表名稱

db_table = "music_album"

資料表名稱

為了節省您的時間,Django 會自動從您的模型類別名稱和包含它的應用程式中衍生出資料庫表名稱。模型的資料庫表名稱的建構方式是將模型的「應用程式標籤」(您在 manage.py startapp 中使用的名稱) 與模型的類別名稱結合,並在它們之間加上底線。

例如,如果您有一個應用程式 bookstore (由 manage.py startapp bookstore 建立),則定義為 class Book 的模型將會具有名為 bookstore_book 的資料庫表。

要覆寫資料庫表名稱,請在 class Meta 中使用 db_table 參數。

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

為 MariaDB 和 MySQL 使用小寫表名稱

強烈建議您在使用 db_table 覆寫表名稱時使用小寫表名稱,特別是當您使用 MySQL 後端時。請參閱MySQL 註解以取得更多詳細資訊。

Oracle 的資料表名稱引用

為了符合 Oracle 對資料表名稱的 30 個字元限制,並符合 Oracle 資料庫的通常慣例,Django 可能會縮短資料表名稱並將它們全部轉換為大寫。若要防止此類轉換,請使用引號名稱作為 db_table 的值

db_table = '"name_left_in_lowercase"'

此類引號名稱也可以與 Django 的其他支援資料庫後端一起使用;但是,除了 Oracle 之外,引號沒有任何作用。請參閱Oracle 註解以取得更多詳細資訊。

db_table_comment

Options.db_table_comment

用於此模型之資料庫表的註解。對於可能無法查看您的 Django 程式碼,但可以直接存取資料庫的個人來說,記錄資料庫表很有用。例如

class Answer(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    answer = models.TextField()

    class Meta:
        db_table_comment = "Question answers"

db_tablespace

Options.db_tablespace

用於此模型的資料庫表空間名稱。預設值是專案的DEFAULT_TABLESPACE設定 (如果已設定)。如果後端不支援表空間,則會忽略此選項。

default_manager_name

Options.default_manager_name

用於模型的 _default_manager的管理員名稱。

get_latest_by

Options.get_latest_by

模型中欄位的名稱或欄位名稱清單,通常是 DateFieldDateTimeFieldIntegerField。這會指定在模型的 Managerlatest()earliest() 方法中使用的預設欄位。

範例

# Latest by ascending order_date.
get_latest_by = "order_date"

# Latest by priority descending, order_date ascending.
get_latest_by = ["-priority", "order_date"]

請參閱 latest() 文件以了解更多資訊。

managed

Options.managed

預設值為 True,表示 Django 會在 migrate 中或作為遷移的一部分建立適當的資料庫表格,並在 flush 管理命令執行時移除它們。也就是說,Django 管理資料庫表格的生命週期。

如果為 False,則不會針對此模型執行任何資料庫表格的建立、修改或刪除操作。如果模型代表現有的表格或透過其他方式建立的資料庫視圖,這會很有用。這是 managed=False唯一的差異。模型處理的所有其他方面都與正常情況完全相同。這包括:

  1. 如果您未宣告,則將自動主鍵欄位新增至模型。為了避免日後程式碼讀者混淆,建議在使用非受管模型時指定您正在建模的資料庫表格中的所有欄。

  2. 如果 managed=False 的模型包含指向另一個非受管模型的 ManyToManyField,則不會建立多對多連線的中介表格。但是,一個受管模型和一個非受管模型之間的中介表格被建立。

    如果您需要變更此預設行為,請將中介表格建立為明確的模型(並根據需要設定 managed),並使用 ManyToManyField.through 屬性使關係使用您的自訂模型。

對於涉及 managed=False 模型的測試,您有責任確保在測試設定中建立正確的表格。

如果您有興趣變更模型類別的 Python 層級行為,您可以使用 managed=False 並建立現有模型的副本。但是,對於這種情況,有一個更好的方法:代理模型

order_with_respect_to

Options.order_with_respect_to

使此物件可根據給定的欄位排序,通常是 ForeignKey。這可用於使相關物件可根據父物件排序。例如,如果 AnswerQuestion 物件相關,並且一個問題有多個答案,而答案的順序很重要,您應該這樣做:

from django.db import models


class Question(models.Model):
    text = models.TextField()
    # ...


class Answer(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    # ...

    class Meta:
        order_with_respect_to = "question"

當設定 order_with_respect_to 時,會提供兩個額外的方法來檢索和設定相關物件的順序:get_RELATED_order()set_RELATED_order(),其中 RELATED 是小寫的模型名稱。例如,假設 Question 物件有多個相關的 Answer 物件,則返回的列表包含相關 Answer 物件的主鍵

>>> question = Question.objects.get(id=1)
>>> question.get_answer_order()
[1, 2, 3]

可以透過傳入 Answer 主鍵的列表來設定 Question 物件相關的 Answer 物件的順序

>>> question.set_answer_order([3, 1, 2])

相關物件也有兩個方法,get_next_in_order()get_previous_in_order(),可用於依其正確順序存取這些物件。假設 Answer 物件按 id 排序

>>> answer = Answer.objects.get(id=2)
>>> answer.get_next_in_order()
<Answer: 3>
>>> answer.get_previous_in_order()
<Answer: 1>

order_with_respect_to 隱式設定 ordering 選項

在內部,order_with_respect_to 會新增一個名為 _order 的額外欄位/資料庫欄,並將模型的 ordering 選項設定為此欄位。因此,order_with_respect_toordering 不能一起使用,並且每當您取得此模型物件列表時,都會套用 order_with_respect_to 新增的排序。

變更 order_with_respect_to

由於 order_with_respect_to 會新增新的資料庫欄,因此如果您在初始的 migrate 之後新增或變更 order_with_respect_to,請務必建立並套用適當的遷移。

ordering

Options.ordering

物件的預設排序,用於取得物件列表時

ordering = ["-order_date"]

這是字串和/或查詢表達式的元組或列表。每個字串都是一個欄位名稱,帶有可選的 "-" 前綴,表示降序。沒有前導 "-" 的欄位將按升序排序。使用字串 "?" 進行隨機排序。

例如,要按升序排序 pub_date 欄位,請使用此方法:

ordering = ["pub_date"]

要按降序排序 pub_date,請使用此方法:

ordering = ["-pub_date"]

要按降序排序 pub_date,然後按升序排序 author,請使用此方法:

ordering = ["-pub_date", "author"]

您也可以使用 查詢表達式。要按升序排序 author 並使 null 值排在最後,請使用此方法:

from django.db.models import F

ordering = [F("author").asc(nulls_last=True)]

警告

排序並非免費操作。您新增至排序的每個欄位都會增加資料庫的成本。您新增的每個外鍵也會隱式包含其所有預設排序。

如果查詢未指定排序,則結果會以未指定的順序從資料庫返回。只有當按照唯一識別結果中每個物件的一組欄位排序時,才能保證特定的排序。例如,如果 name 欄位不是唯一的,則按其排序並不能保證具有相同名稱的物件始終以相同的順序顯示。

permissions

Options.permissions

在建立此物件時要輸入到權限表格中的額外權限。會為每個模型自動建立新增、變更、刪除和檢視權限。此範例指定額外的權限 can_deliver_pizzas

permissions = [("can_deliver_pizzas", "Can deliver pizzas")]

這是一個 2 元組的列表或元組,格式為 (permission_code, human_readable_permission_name)

default_permissions

Options.default_permissions

預設值為 ('add', 'change', 'delete', 'view')。您可以自訂此列表,例如,如果您的應用程式不需要任何預設權限,則將其設定為空列表。必須在透過 migrate 建立模型之前,在模型上指定,以防止建立任何省略的權限。

proxy

Options.proxy

如果 proxy = True,則將繼承另一個模型的模型視為 代理模型

required_db_features

Options.required_db_features

資料庫功能的列表,目前的連線必須具備這些功能,模型才會在遷移階段被考慮。例如,如果您將此列表設定為 ['gis_enabled'],則該模型只會在啟用 GIS 的資料庫上進行同步。這在測試多個資料庫後端時,跳過某些模型也很有用。請避免可能建立或不建立的模型之間的關聯,因為 ORM 無法處理這種情況。

required_db_vendor

Options.required_db_vendor

此模型所特定的受支援資料庫供應商名稱。目前內建的供應商名稱有:sqlitepostgresqlmysqloracle。如果此屬性不為空,且目前連線的供應商與之不符,則該模型將不會被同步。

select_on_save

Options.select_on_save

決定 Django 是否會使用 1.6 版之前的 django.db.models.Model.save() 演算法。舊的演算法會使用 SELECT 來判斷是否有現有的列需要更新。新的演算法則會直接嘗試 UPDATE。在某些罕見的情況下,現有列的 UPDATE 對於 Django 是不可見的。例如,PostgreSQL 的 ON UPDATE 觸發器會傳回 NULL。在這種情況下,即使資料庫中存在列,新的演算法最終還是會執行 INSERT

通常沒有必要設定此屬性。預設值為 False

有關舊的和新的儲存演算法的更多資訊,請參閱 django.db.models.Model.save()

indexes

Options.indexes

您想要在模型上定義的 索引 列表

from django.db import models


class Customer(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)

    class Meta:
        indexes = [
            models.Index(fields=["last_name", "first_name"]),
            models.Index(fields=["first_name"], name="first_name_idx"),
        ]

unique_together

Options.unique_together

請改用具有 constraints 選項的 UniqueConstraint

UniqueConstraint 提供了比 unique_together 更多的功能。unique_together 未來可能會被棄用。

欄位名稱的集合,組合起來必須是唯一的

unique_together = [["driver", "restaurant"]]

這是一個列表的列表,當一起考慮時必須是唯一的。它在 Django 管理介面中使用,並在資料庫層級強制執行(即,適當的 UNIQUE 陳述式會包含在 CREATE TABLE 陳述式中)。

為了方便起見,當處理單一欄位集合時,unique_together 可以是單一列表

unique_together = ["driver", "restaurant"]

ManyToManyField 不能包含在 unique_together 中。(甚至不清楚那會是什麼意思!)如果您需要驗證與 ManyToManyField 相關的唯一性,請嘗試使用信號或明確的 through 模型。

當違反約束時,模型驗證期間引發的 ValidationError 具有 unique_together 錯誤碼。

constraints

Options.constraints

您想要在模型上定義的 約束 列表

from django.db import models


class Customer(models.Model):
    age = models.IntegerField()

    class Meta:
        constraints = [
            models.CheckConstraint(condition=models.Q(age__gte=18), name="age_gte_18"),
        ]

verbose_name

Options.verbose_name

物件的易讀名稱,單數

verbose_name = "pizza"

如果未提供,Django 將使用類別名稱的修改版本:CamelCase 會變成 camel case

verbose_name_plural

Options.verbose_name_plural

物件的複數名稱

verbose_name_plural = "stories"

如果未提供,Django 將使用 verbose_name + "s"

唯讀的 Meta 屬性

label

Options.label

物件的表示形式,傳回 app_label.object_name,例如 'polls.Question'

label_lower

Options.label_lower

模型的表示形式,傳回 app_label.model_name,例如 'polls.question'

返回頂部