模型的元數據,指的是「除了字段外的全部內容」,例如排序方式、數據庫表名、人類可讀的單數或者複數名等等。全部的這些都是非必須的,甚至元數據自己對模型也是非必須的。可是,我要說可是,有些元數據選項能給予你極大的幫助,在實際使用中具備重要的做用,是實際應用的‘必須’。python
想在模型中增長元數據,方法很簡單,在模型類中添加一個子類,名字是固定的Meta
,而後在這個Meta類下面增長各類元數據選項或者說設置項。參考下面的例子:mysql
from django.db import models class Ox(models.Model): horn_length = models.IntegerField() class Meta: # 注意,是模型的子類,要縮進! ordering = ["horn_length"] verbose_name_plural = "oxen"
上面的例子中,咱們爲模型Ox增長了兩個元數據‘ordering’和‘verbose_name_plural’,分別表示排序和複數名,下面咱們會詳細介紹有哪些可用的元數據選項。算法
強調:每一個模型均可以有本身的元數據類,每一個元數據類也只對本身所在模型起做用。sql
若是abstract=True
,那麼模型會被認爲是一個抽象模型。抽象模型自己不實際生成數據庫表,而是做爲其它模型的父類,被繼承使用。具體內容能夠參考Django模型的繼承。數據庫
若是定義了模型的app沒有在INSTALLED_APPS
中註冊,則必須經過此元選項聲明它屬於哪一個app,例如:django
app_label = 'myapp'
自定義模型的_base_manager
管理器的名字。模型管理器是Django爲模型提供的API所在。Django1.10新增。oracle
指定在數據庫中,當前模型生成的數據表的表名。好比:app
db_table = 'my_freinds'
友情建議:使用MySQL數據庫時,db_table
用小寫英文。post
自定義數據庫表空間的名字。默認值是工程的DEFAULT_TABLESPACE
設置。ui
自定義模型的_default_manager
管理器的名字。Django1.10新增。
默認狀況下,從一個模型反向關聯設置有關係字段的源模型,咱們使用<model_name>_set
,也就是源模型的名字+下劃線+set
。
這個元數據選項可讓你自定義反向關係名,同時也影響反向查詢關係名!看下面的例子:
from django.db import models class Foo(models.Model): pass class Bar(models.Model): foo = models.ForeignKey(Foo) class Meta: default_related_name = 'bars' # 關鍵在這裏
具體的使用差異以下:
>>> bar = Bar.objects.get(pk=1) >>> # 不能再使用"bar"做爲反向查詢的關鍵字了。 >>> Foo.objects.get(bar=bar) >>> # 而要使用你本身定義的"bars"了。 >>> Foo.objects.get(bars=bar)
Django管理器給咱們提供有latest()和earliest()方法,分別表示獲取最近一個和最前一個數據對象。可是,如何來判斷最近一個和最前面一個呢?也就是根據什麼來排序呢?
get_latest_by
元數據選項幫你解決這個問題,它能夠指定一個相似 DateField
、DateTimeField
或者IntegerField
這種能夠排序的字段,做爲latest()和earliest()方法的排序依據,從而得出最近一個或最前面一個對象。例如:
get_latest_by = "order_date"
該元數據默認值爲True,表示Django將按照既定的規則,管理數據庫表的生命週期。
若是設置爲False,將不會針對當前模型建立和刪除數據庫表。在某些場景下,這可能有用,但更多時候,你能夠忘記該選項。
這個選項很差理解。其用途是根據指定的字段進行排序,一般用於關係字段。看下面的例子:
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'
上面在Answer模型中設置了order_with_respect_to = 'question'
,這樣的話,Django會自動提供兩個API,get_RELATED_order()
和set_RELATED_order()
,其中的RELATED
用小寫的模型名代替。假設如今有一個Question對象,它關聯着多個Answer對象,下面的操做返回包含關聯的Anser對象的主鍵的列表[1,2,3]:
>>> question = Question.objects.get(id=1) >>> question.get_answer_order() [1, 2, 3]
咱們能夠經過set_RELATED_order()
方法,指定上面這個列表的順序:
>>> question.set_answer_order([3, 1, 2])
一樣的,關聯的對象也得到了兩個方法get_next_in_order()
和get_previous_in_order()
,用於經過特定的順序訪問對象,以下所示:
>>> answer = Answer.objects.get(id=2) >>> answer.get_next_in_order() <Answer: 3> >>> answer.get_previous_in_order() <Answer: 1>
這個元數據的做用......還沒用過,囧。
最經常使用的元數據之一了!
用於指定該模型生成的全部對象的排序方式,接收一個字段名組成的元組或列表。默認按升序排列,若是在字段名前加上字符「-」則表示按降序排列,若是使用字符問號「?」表示隨機排列。請看下面的例子:
ordering = ['pub_date'] # 表示按'pub_date'字段進行升序排列 ordering = ['-pub_date'] # 表示按'pub_date'字段進行降序排列 ordering = ['-pub_date', 'author'] # 表示先按'pub_date'字段進行降序排列,再按`author`字段進行升序排列。
該元數據用於當建立對象時增長額外的權限。它接收一個全部元素都是二元元組的列表或元組,每一個元素都是(權限代碼, 直觀的權限名稱)
的格式。好比下面的例子:
permissions = (("can_deliver_pizzas", "能夠送披薩"),)
Django默認給全部的模型設置('add', 'change', 'delete')的權限,也就是增刪改。你能夠自定義這個選項,好比設置爲一個空列表,表示你不須要默認的權限,可是這一操做必須在執行migrate命令以前。
若是設置了proxy = True
,表示使用代理模式的模型繼承方式。具體內容與abstract選項同樣,參考模型繼承章節。
聲明模型依賴的數據庫功能。好比['gis_enabled'],表示模型的創建依賴GIS功能。
聲明模型支持的數據庫。Django默認支持sqlite, postgresql, mysql, oracle
。
決定是否使用1.6版本以前的django.db.models.Model.save()
算法保存對象。默認值爲False。這個選項咱們一般不用關心。
Django1.11新增的選項。
接收一個應用在當前模型上的索引列表,以下例所示:
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'), ]
這個元數據是很是重要的一個!它等同於數據庫的聯合約束!
舉個例子,假設有一張用戶表,保存有用戶的姓名、出生日期、性別和籍貫等等信息。要求是全部的用戶惟一不重複,可如今有好幾個叫「張偉」的,如何區別它們呢?(不要和我說主鍵惟一,這裏討論的不是這個問題)
咱們能夠設置不能有兩個用戶在同一個地方同一時刻出生而且都叫「張偉」,使用這種聯合約束,保證數據庫能不能重複添加用戶(也不要和我談小几率問題)。在Django的模型中,如何實現這種約束呢?
使用unique_together
,也就是聯合惟一!
好比:
unique_together = (('name', 'birth_day', 'address'),)
這樣,哪怕有兩個在同一天出生的張偉,但他們的籍貫不一樣,也就是兩個不一樣的用戶。一旦三者都相同,則會被Django拒絕建立。這一元數據常常被用在admin後臺,而且強制應用於數據庫層面。
unique_together接收一個二維的元組((xx,xx,xx,...),(),(),()...),每個元素都是一個元組,表示一組聯合惟一約束,能夠同時設置多組約束。爲了方便,對於只有一組約束的狀況下,能夠簡單地使用一維元素,例如:
unique_together = ('name', 'birth_day', 'address')
聯合惟一沒法做用於普通的多對多字段。
即將廢棄,使用index
元數據代替。
最經常使用的元數據之一!用於設置模型對象的直觀、人類可讀的名稱。能夠用中文。例如:
verbose_name = "story" verbose_name = "披薩"
若是你不指定它,那麼Django會使用小寫的模型名做爲默認值。
英語有單數和複數形式。這個就是模型對象的複數名,好比「apples」。由於咱們中文一般不區分單複數,因此保持和verbose_name
一致也能夠。
verbose_name_plural = "stories" verbose_name_plural = "披薩"
若是不指定該選項,那麼默認的複數名字是verbose_name
加上‘s’
前面介紹的元數據都是可修改和設置的,但還有兩個只讀的元數據,label就是其中之一。
label等同於app_label.object_name
。例如polls.Question
,polls是應用名,Question是模型名。
同上,不過是小寫的模型名。