使用內部的class Meta 定義模型的元數據,例如:python
from django.db import models class Ox(models.Model): horn_length = models.IntegerField() class Meta: ordering = ["horn_length"] verbose_name_plural = "oxen"
模型元數據是「任何不是字段的數據」,好比排序選項(ordering),數據庫表名(db_table)或者人類可讀的單複數名稱(verbose_name 和verbose_name_plural)。在模型中添加class Meta是徹底可選的,全部選項都不是必須的。算法
Options.abstract
若是 abstract = True, 就表示模型是 抽象基類 (abstract base class).數據庫
Options.app_label
若是一個模型位於標準的位置以外(應用的models.py 或models 包),該模型必須定義它屬於哪一個應用:django
app_label = 'myapp'
New in Django 1.7:
定義在應用的models 模塊之外的模型,再也不須要app_label。後端
Options.db_table
該模型所用的數據表的名稱:app
db_table = 'music_album'
爲節省你的時間,Django 會根據模型類的名稱和包含它的應用的名稱自動指定數據庫表名稱。一個模型的數據庫表名稱,由這個模型的「應用標籤」(在manage.py startapp中使用的名稱)和模型類名稱之間加上下劃線組成。測試
舉個例子, bookstore應用(使用 manage.py startapp bookstore 建立),裏面有個名爲 Book的模型,那數據表的名稱就是 bookstore_book 。spa
使用 Meta類中的 db_table 參數來重寫數據表的名稱。設計
數據表名稱能夠是 SQL 保留字,也能夠包含不容許出如今 Python 變量中的特殊字符,這是由於 Django 會自動給列名和表名添加引號。代理
在 MySQL中使用小寫字母爲表命名
當你經過db_table覆寫表名稱時,強烈推薦使用小寫字母給表命名,特別是若是你用了MySQL做爲後端。詳見MySQL注意事項 。
Oracle中表名稱的引號處理
爲了聽從Oracle中30個字符的限制,以及一些常見的約定,Django會縮短表的名稱,並且會把它所有轉爲大寫。在db_table的值外面加上引號來避免這種狀況:
db_table = '"name_left_in_lowercase"'
這種帶引號的名稱也能夠用於Django所支持的其餘數據庫後端,可是除了Oracle,引號不起任何做用。詳見 Oracle 注意事項 。
Options.db_tablespace
當前模型所使用的數據庫表空間 的名字。默認值是項目設置中的DEFAULT_TABLESPACE,若是它存在的話。若是後端並不支持表空間,這個選項能夠忽略。
Options.default_related_name
New in Django 1.8.
這個名字會默認被用於一個關聯對象到當前對象的關係。默認爲 <model_name>_set。
因爲一個字段的反轉名稱應該是惟一的,當你給你的模型設計子類時,要格外當心。爲了規避名稱衝突,名稱的一部分應該含有'%(app_label)s'和'%(model_name)s',它們會被應用標籤的名稱和模型的名稱替換,兩者都是小寫的。詳見抽象模型的關聯名稱。
Options.get_latest_by
模型中某個可排序的字段的名稱,好比DateField、DateTimeField或者IntegerField。它指定了Manager的latest()和earliest()中使用的默認字段。
例如:
get_latest_by = "order_date"
詳見latest() 文檔。
Options.managed
默認爲True,意思是Django在migrate命令中建立合適的數據表,而且會在 flush 管理命令中移除它們。換句話說,Django會管理這些數據表的生命週期。
若是是False,Django 就不會爲當前模型建立和刪除數據表。若是當前模型表示一個已經存在的,經過其它方法創建的數據庫視圖或者數據表,這會至關有用。這是設置爲managed=False時惟一的不一樣之處。. 模型處理的其它任何方面都和日常同樣。這包括:
若是你不聲明它的話,會向你的模型中添加一個自增主鍵。爲了不給後面的代碼讀者帶來混亂,強烈推薦你在使用未被管理的模型時,指定數據表中全部的列。
若是一個帶有managed=False的模型含有指向其餘未被管理模型的ManyToManyField,那麼多對多鏈接的中介表也不會被建立。可是,一個被管理模型和一個未被管理模型之間的中介表會被建立。
若是你須要修改這一默認行爲,建立中介表做爲顯式的模型(設置爲managed),而且使用ManyToManyField.through爲你的自定義模型建立關聯。
對於帶有managed=False的模型的測試,你要確保在測試啓動時創建正確的表。
若是你對修改模型類在Python層面的行爲感興趣,你能夠設置 managed=False ,而且爲一個已經存在的模型建立一個副本。可是這種狀況下使用代理模型纔是更好的方法。
Options.order_with_respect_to
按照給定的字段把這個對象標記爲」可排序的「。這一屬性一般用到關聯對象上面,使它在父對象中有序。好比,若是Answer和 Question相關聯,一個問題有至少一個答案,而且答案的順序很是重要,你能夠這樣作:
from django.db import models class Question(models.Model): text = models.TextField() # ... class Answer(models.Model): question = models.ForeignKey(Question) # ... 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]
與Question對象相關聯的Answer對象的順序,能夠經過傳入一格包含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
order_with_respect_to屬性會添加一個額外的字段(/數據表中的列)叫作_order,因此若是你在首次遷移以後添加或者修改了order_with_respect_to屬性,要確保執行和應用了合適的遷移操做。
Options.ordering
對象默認的順序,獲取一個對象的列表時使用:
ordering = ['-order_date']
它是一個字符串的列表或元組。每一個字符串是一個字段名,前面帶有可選的「-」前綴表示倒序。前面沒有「-」的字段表示正序。使用"?"來表示隨機排序。
例如,要按照pub_date字段的正序排序,這樣寫:
ordering = ['pub_date']
按照pub_date字段的倒序排序,這樣寫:
ordering = ['-pub_date']
先按照pub_date的倒序排序,再按照 author 的正序排序,這樣寫:
ordering = ['-pub_date', 'author']
警告
排序並非沒有任何代價的操做。你向ordering屬性添加的每一個字段都會產生你數據庫的開銷。你添加的每一個外鍵也會隱式包含它的默認順序。
Options.permissions
設置建立對象時權限表中額外的權限。增長、刪除和修改權限會自動爲每一個模型建立。這個例子指定了一種額外的權限,can_deliver_pizzas:
permissions = (("can_deliver_pizzas", "Can deliver pizzas"),)
它是一個包含二元組的元組或者列表,格式爲 (permission_code, human_readable_permission_name)。
Options.default_permissions
New in Django 1.7.
默認爲('add', 'change', 'delete')。你能夠自定義這個列表,好比,若是你的應用不須要默認權限中的任何一項,能夠把它設置成空列表。在模型被migrate命令建立以前,這個屬性必須被指定,以防一些遺漏的屬性被建立。
Options.proxy
若是proxy = True, 它做爲另外一個模型的子類,將會做爲一個代理模型。
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()。
Options.unique_together
用來設置的不重複的字段組合:
unique_together = (("driver", "restaurant"),)
它是一個元組的元組,組合起來的時候必須是惟一的。它在Django後臺中被使用,在數據庫層上約束數據(好比,在 CREATE TABLE 語句中包含 UNIQUE語句)。
爲了方便起見,處理單一字段的集合時,unique_together 能夠是一維的元組:
unique_together = ("driver", "restaurant")
ManyToManyField不能包含在unique_together中。(這意味着什麼並不清楚!)若是你須要驗證ManyToManyField關聯的惟一性,試着使用信號或者顯式的貫穿模型(explicit through model)。
Changed in Django 1.7:
當unique_together的約束被違反時,模型校驗期間會拋出ValidationError異常。
Options.index_together
用來設置帶有索引的字段組合:
index_together = [
["pub_date", "deadline"],
]
列表中的字段將會創建索引(例如,會在CREATE INDEX語句中被使用)。
Changed in Django 1.7.
爲了方便起見,處理單一字段的集合時,index_together能夠是一個一維的列表。
index_together = ["pub_date", "deadline"]
Options.verbose_name
對象的一個易於理解的名稱,爲單數:
verbose_name = "pizza"
若是此項沒有設置,Django會把類名拆分開來做爲自述名,好比CamelCase 會變成camel case,
Options.verbose_name_plural
該對象複數形式的名稱:
verbose_name_plural = "stories" 若是此項沒有設置,Django 會使用 verbose_name + "s"。