接著上篇文章內(nèi)容,本文分享自己對模型一些用法的總結(jié)。
1 模型的元數(shù)據(jù)Meta
除了抽象模型废膘,在模型中定義的字段都會成為表中的列。如果我們需要給模型指定其他一些信息慕蔚,例如排序方式丐黄、數(shù)據(jù)庫表名等,就需要用到 Meta孔飒。Meta 是一個可選的類灌闺,具體用法如下:
class Author(models.Model):
name = models.CharField(max_length=40)
email = models.EmailField()
class Meta:
managed = True
db_table = 'author'
不知你是否對上述代碼有影響。通過 Django 將數(shù)據(jù)庫表反向生成模型時坏瞄,Django 會默認(rèn)帶上 managed 和 db_table 信息桂对。
我主要說下 Meta 一些重要的屬性,其他屬性你可以通過文檔信息進(jìn)行學(xué)習(xí)惦积。
abstract: 如果 abstract = True,模型會指定為抽象模型猛频。它相當(dāng)于面向?qū)ο缶幊讨械某橄蠡悺?/p>
proxy:如果設(shè)置了proxy = True狮崩,表示使用代理模式的模型繼承方式。
db_table:指定當(dāng)前模型在數(shù)據(jù)庫的表名鹿寻。
managed:該屬性默認(rèn)值為 True睦柴,表示能創(chuàng)建模型和操作數(shù)據(jù)庫表。
ordering:指定該模型生成的所有對象的排序方式毡熏。默認(rèn)按升序排列坦敌,如果在字段名前加上字符 “-” 則表示按降序排列,如果使用字符問號 “痢法?” 表示隨機排列狱窘。
ordering = ['pub_date'] # 表示按'pub_date'字段進(jìn)行升序排列
ordering = ['-pub_date'] # 表示按'pub_date'字段進(jìn)行降序排列
ordering = ['-pub_date', 'author'] # 表示先按'pub_date'字段進(jìn)行降序排列,再按`author`字段進(jìn)行升序排列财搁。
verbose_name:給模型設(shè)置別名蘸炸。如果不指定它,Django 會使用小寫的模型名作為默認(rèn)值尖奔。
verbose_name = "book"
verbose_name = "圖書"
verbose_name_plural:因為英語單詞有單數(shù)和復(fù)數(shù)兩種形式搭儒,這個屬性是模型對象的復(fù)數(shù)名。中文則跟 verbose_name 值一致提茁。如果不指定該選項淹禾,那么默認(rèn)的復(fù)數(shù)名字是 verbose_name 加上 ‘s’ 。
verbose_name_plural = "books"
verbose_name_plural = "圖書"
indexes:為當(dāng)前模型建立索引列表茴扁。用法如下:
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'),
]
2 模型的繼承
根據(jù)模型的 Meta 信息設(shè)置铃岔,模型繼承方式可以分為三種:
1)抽象模型
模型的 Meta 類中含有 abstract = True 屬性。抽象模型一般被當(dāng)作基類峭火,它持有子類共有的字段德撬。值得注意的是铲咨,抽象模型在數(shù)據(jù)庫中不會生成表。
from django.db import models
# 抽象模型
class Person(models.Model):
name = models.CharField(max_length=500)
age = models.PositiveIntegerField()
class Meta:
abstract = True
# 子模型
class Student(Person):
school_name = models.CharField(max_length=20)
子模型如果沒有定義 Meta 類蜓洪,那么會繼承抽象模型的 Meta 類纤勒。但是 abstract 屬性不會被繼承。
2)多表繼承
這種方式繼承方式隆檀,子模型的父模型可以一個或者多個摇天。
當(dāng)父類模型是正常的模型,即不是抽象模型恐仑,在數(shù)據(jù)庫中有對應(yīng)表泉坐。
雖然在 Model 層不推薦使用多重繼承,但 Django 的 ORM 還是支持這樣的使用方式裳仆。如果使用多表繼承腕让,子模型跟每個父模型都會添加一個一對一的關(guān)系。
from django.db import models
# 父模型 one
class Model_One(models.Model):
attr1 = models.CharField(max_length=10)
# 父模型 two
class Model_Two(models.Model):
attr2 = models.CharField(max_length=10)
# 子模型
class Multiple(Model_One, Model_Two):
attr3 = models.CharField(max_length=10)
多重繼承的時候歧斟,子類的 ORM 映射會選擇第一個父類作為主鍵管理纯丸,其他的父類作為一般的外鍵管理。
3)代理模型
使用多表繼承時静袖,父類的每個子類都會創(chuàng)建一張新數(shù)據(jù)表觉鼻。但是我們只是想擴展一些方法,而不想改變模型的數(shù)據(jù)存儲結(jié)構(gòu)队橙。我們可以將在 Meta 類中增加約束proxy=True 來實現(xiàn)坠陈。此時子模型稱為父模型的代理類,子類中只能增加方法捐康,而不能增加屬性仇矾。
from django.db import models
from django.contrib.auth.models import User
class Person(User):
name = models.CharField(max_length=10)
class Meta:
proxy = True
def do_something(self):
pass
class Man(Person):
job = models.CharField(max_length=20)
class Woman(Person):
makeup = models.CharField(max_length=20)
3 寫在最后
我新建一個 Python Web 學(xué)習(xí)交流 QQ 群,群號:701534112解总。歡迎大家加群若未,一起交流,一起學(xué)習(xí)倾鲫,一起進(jìn)步粗合。
往前 Django 學(xué)習(xí)筆記文章
Django 學(xué)習(xí)筆記之環(huán)境搭建
Django 學(xué)習(xí)筆記之初始
Django 學(xué)習(xí)筆記之視圖與URL配置
Django 學(xué)習(xí)筆記之模板
Django 學(xué)習(xí)筆記之模型(上)
Django 學(xué)習(xí)筆記之模型(下)
Django 學(xué)習(xí)筆記之后臺管理
Django 學(xué)習(xí)筆記之模型表單
Django 學(xué)習(xí)筆記之使用舊數(shù)據(jù)庫
Django 實戰(zhàn)1:搭建屬于自己社工查詢系統(tǒng)(上)
Django 實戰(zhàn)1:搭建屬于自己社工查詢系統(tǒng)(下)
Django 學(xué)習(xí)筆記之模型高級用法(上)
本文原創(chuàng)發(fā)布于微信公眾號「極客猴」,歡迎關(guān)注第一時間獲取更多原創(chuàng)分享