這篇文檔闡述了所有可用的元選項(xiàng),你可以在你模型的Meta類(lèi)中設(shè)置他們。
Options.abstract
如果 abstract = True, 就表示模型是 抽象基類(lèi) (abstract base class).
Options.app_label
如果你的模型定義在默認(rèn)的 models.py 之外(比如,你現(xiàn)在用的模型在 myapp.models 子模塊當(dāng)中),你必須告訴 Django 該模型屬于哪個(gè)應(yīng)用:
app_label = 'myapp'
Django 1.7中新增:
一個(gè)應(yīng)用中,定義在models 模塊以外的模型,不再需要app_label。
Options.db_table
該模型所用的數(shù)據(jù)表的名稱:
db_table = 'music_album'
為了節(jié)省時(shí)間,Django 會(huì)根據(jù)模型類(lèi)的名稱和包含它的app名稱自動(dòng)指定數(shù)據(jù)表名稱,一個(gè)模型的數(shù)據(jù)表名稱,由這個(gè)模型的“應(yīng)用標(biāo)簽”(在 manage.py startapp中使用的名稱)之間加上下劃線組成。
舉個(gè)例子, bookstore應(yīng)用(使用 manage.py startapp bookstore 創(chuàng)建),里面有個(gè)名為 Book的模型,那數(shù)據(jù)表的名稱就是 bookstore_book 。
使用 Meta類(lèi)中的 db_table 參數(shù)來(lái)覆寫(xiě)數(shù)據(jù)表的名稱。
數(shù)據(jù)表名稱可以是 SQL 保留字,也可以包含不允許出現(xiàn)在 Python 變量中的特殊字符,這是因?yàn)?Django 會(huì)自動(dòng)給列名和表名添加引號(hào)。
在 MySQL中使用小寫(xiě)字母為表命名
當(dāng)你通過(guò)db_table覆寫(xiě)表名稱時(shí),強(qiáng)烈推薦使用小寫(xiě)字母給表命名,特別是如果你用了MySQL作為后端。詳見(jiàn)MySQL注意事項(xiàng) 。
Oracle中表名稱的引號(hào)處理
為了遵從Oracle中30個(gè)字符的限制,以及一些常見(jiàn)的約定,Django會(huì)縮短表的名稱,而且會(huì)把它全部轉(zhuǎn)為大寫(xiě)。在db_table的值外面加上引號(hào)來(lái)避免這種情況:
db_table = '"name_left_in_lowercase"'這種帶引號(hào)的名稱也可以用于Django所支持的其他數(shù)據(jù)庫(kù)后端,但是除了Oracle,引號(hào)不起任何作用。詳見(jiàn) Oracle 注意事項(xiàng) 。
Options.db_tablespace
當(dāng)前模型所使用的數(shù)據(jù)庫(kù)表空間 的名字。默認(rèn)值是項(xiàng)目設(shè)置中的DEFAULT_TABLESPACE,如果它存在的話。如果后端并不支持表空間,這個(gè)選項(xiàng)可以忽略。
Options.default_related_name
Django 1.8中新增:
這個(gè)名字會(huì)默認(rèn)被用于一個(gè)關(guān)聯(lián)對(duì)象到當(dāng)前對(duì)象的關(guān)系。默認(rèn)為
由于一個(gè)字段的反轉(zhuǎn)名稱應(yīng)該是唯一的,當(dāng)你給你的模型設(shè)計(jì)子類(lèi)時(shí),要格外小心。為了規(guī)避名稱沖突,名稱的一部分應(yīng)該含有'%(app_label)s'和'%(model_name)s',它們會(huì)被應(yīng)用標(biāo)簽的名稱和模型的名稱替換,二者都是小寫(xiě)的。詳見(jiàn)抽象模型的關(guān)聯(lián)名稱。
Options.get_latest_by
模型中某個(gè)可排序的字段的名稱,比如DateField、DateTimeField或者IntegerField。它指定了Manager的latest()和earliest()中使用的默認(rèn)字段。
例如:
get_latest_by = "order_date"
詳見(jiàn)latest() 文檔。
Options.managed
默認(rèn)為T(mén)rue,意思是Django在migrate命令中創(chuàng)建合適的數(shù)據(jù)表,并且會(huì)在 flush 管理命令中移除它們。換句話說(shuō),Django會(huì)管理這些數(shù)據(jù)表的生命周期。
如果是False,Django 就不會(huì)為當(dāng)前模型創(chuàng)建和刪除數(shù)據(jù)表。如果當(dāng)前模型表示一個(gè)已經(jīng)存在的,通過(guò)其它方法建立的數(shù)據(jù)庫(kù)視圖或者數(shù)據(jù)表,這會(huì)相當(dāng)有用。這是設(shè)置為managed=False時(shí)唯一的不同之處。. 模型處理的其它任何方面都和平常一樣。這包括:
如果你需要修改這一默認(rèn)行為,創(chuàng)建中介表作為顯式的模型(設(shè)置為managed),并且使用ManyToManyField.through為你的自定義模型創(chuàng)建關(guān)聯(lián)。
對(duì)于帶有managed=False的模型的測(cè)試,你要確保在測(cè)試啟動(dòng)時(shí)建立正確的表。
如果你對(duì)修改模型類(lèi)在Python層面的行為感興趣,你可以設(shè)置 managed=False ,并且創(chuàng)建一個(gè)已經(jīng)存在模型的部分。但是這種情況下使用代理模型才是更好的方法。
Options.order_with_respect_to
按照給定的字段把這個(gè)對(duì)象標(biāo)記為”可排序的“。這一屬性通常用到關(guān)聯(lián)對(duì)象上面,使它在父對(duì)象中有序。比如,如果Answer和 Question相關(guān)聯(lián),一個(gè)問(wèn)題有至少一個(gè)答案,并且答案的順序非常重要,你可以這樣做:
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'
當(dāng)order_with_respect_to 設(shè)置之后,模型會(huì)提供兩個(gè)用于設(shè)置和獲取關(guān)聯(lián)對(duì)象順序的方法:get_RELATED_order() 和set_RELATED_order(),其中RELATED是小寫(xiě)的模型名稱。例如,假設(shè)一個(gè) Question 對(duì)象有很多相關(guān)聯(lián)的Answer對(duì)象,返回的列表中含有相關(guān)聯(lián)Answer對(duì)象的主鍵:
>>> question = Question.objects.get(id=1)
>>> question.get_answer_order()
[1, 2, 3]
與Question對(duì)象相關(guān)聯(lián)的Answer對(duì)象的順序,可以通過(guò)傳入一格包含Answer 主鍵的列表來(lái)設(shè)置:
>>> question.set_answer_order([3, 1, 2])
相關(guān)聯(lián)的對(duì)象也有兩個(gè)方法, get_next_in_order() 和get_previous_in_order(),用于按照合適的順序訪問(wèn)它們。假設(shè)Answer對(duì)象按照 id來(lái)排序:
>>> 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屬性會(huì)添加一個(gè)額外的字段(/數(shù)據(jù)表中的列)叫做_order,所以如果你在首次遷移之后添加或者修改了order_with_respect_to屬性,要確保執(zhí)行和應(yīng)用了合適的遷移操作。
Options.ordering
對(duì)象默認(rèn)的順序,獲取一個(gè)對(duì)象的列表時(shí)使用:
ordering = ['-order_date']
它是一個(gè)字符串的列表或元組。每個(gè)字符串是一個(gè)字段名,前面帶有可選的“-”前綴表示倒序。前面沒(méi)有“-”的字段表示正序。使用"?"來(lái)表示隨機(jī)排序。
例如,要按照pub_date字段的正序排序,這樣寫(xiě):
ordering = ['pub_date']
按照pub_date字段的倒序排序,這樣寫(xiě):
ordering = ['-pub_date']
先按照pub_date的倒序排序,再按照 author 的正序排序,這樣寫(xiě):
ordering = ['-pub_date', 'author']
警告
排序并不是沒(méi)有任何代價(jià)的操作。你向ordering屬性添加的每個(gè)字段都會(huì)產(chǎn)生你數(shù)據(jù)庫(kù)的開(kāi)銷(xiāo)。你添加的每個(gè)外鍵也會(huì)隱式包含它的默認(rèn)順序。
Options.permissions
設(shè)置創(chuàng)建對(duì)象時(shí)權(quán)限表中額外的權(quán)限。增加、刪除和修改權(quán)限會(huì)自動(dòng)為每個(gè)模型創(chuàng)建。這個(gè)例子指定了一種額外的權(quán)限,can_deliver_pizzas:
permissions = (("can_deliver_pizzas", "Can deliver pizzas"),)
它是一個(gè)包含二元組的元組或者列表,格式為 (permission_code, human_readable_permission_name)。
Options.default_permissions
Django 1.7中新增:
默認(rèn)為('add', 'change', 'delete')。你可以自定義這個(gè)列表,比如,如果你的應(yīng)用不需要默認(rèn)權(quán)限中的任何一項(xiàng),可以把它設(shè)置成空列表。在模型被migrate命令創(chuàng)建之前,這個(gè)屬性必須被指定,以防一些遺漏的屬性被創(chuàng)建。
Options.proxy
如果proxy = True, 作為該模型子類(lèi)的另一個(gè)模型會(huì)被視為代理模型。
Options.select_on_save
該選項(xiàng)決定了Django是否采用1.6之前的 django.db.models.Model.save()算法。舊的算法使用SELECT來(lái)判斷是否存在需要更新的行。而新式的算法直接嘗試使用 UPDATE。在一些小概率的情況中,一個(gè)已存在的行的UPDATE操作并不對(duì)Django可見(jiàn)。比如PostgreSQL的ON UPDATE觸發(fā)器會(huì)返回NULL。這種情況下,新式的算法會(huì)在最后執(zhí)行 INSERT 操作,即使這一行已經(jīng)在數(shù)據(jù)庫(kù)中存在。
通常這個(gè)屬性不需要設(shè)置。默認(rèn)為False。
關(guān)于舊式和新式兩種算法,請(qǐng)參見(jiàn)django.db.models.Model.save()。
Options.unique_together
用來(lái)設(shè)置的不重復(fù)的字段組合:
unique_together = (("driver", "restaurant"),)
它是一個(gè)元組的元組,組合起來(lái)的時(shí)候必須是唯一的。它在Django后臺(tái)中被使用,在數(shù)據(jù)庫(kù)層上約束數(shù)據(jù)(比如,在 CREATE TABLE 語(yǔ)句中包含 UNIQUE語(yǔ)句)。
為了方便起見(jiàn),處理單一字段的集合時(shí),unique_together 可以是一維的元組:
unique_together = ("driver", "restaurant")
ManyToManyField不能包含在unique_together中。(這意味著什么并不清楚?。┤绻阈枰?yàn)證ManyToManyField關(guān)聯(lián)的唯一性,試著使用信號(hào)或者顯式的貫穿模型(explicit through model)。
Django 1.7中修改:
當(dāng)unique_together的約束被違反時(shí),模型校驗(yàn)期間會(huì)拋出ValidationError異常。
Options.index_together
用來(lái)設(shè)置帶有索引的字段組合:
index_together = [
["pub_date", "deadline"],
]
列表中的字段將會(huì)建立索引(例如,會(huì)在CREATE INDEX語(yǔ)句中被使用)。
Django 1.7中修改:
為了方便起見(jiàn),處理單一字段的集合時(shí),index_together可以是一個(gè)一維的列表。
index_together = ["pub_date", "deadline"]
Options.verbose_name
對(duì)象的一個(gè)易于理解的名稱,為單數(shù):
verbose_name = "pizza"
如果此項(xiàng)沒(méi)有設(shè)置,Django會(huì)把類(lèi)名拆分開(kāi)來(lái)作為自述名,比如CamelCase 會(huì)變成camel case,
Options.verbose_name_plural
該對(duì)象復(fù)數(shù)形式的名稱:
verbose_name_plural = "stories"
如果此項(xiàng)沒(méi)有設(shè)置,Django 會(huì)使用 verbose_name + "s"。