Python使用描述器實(shí)現(xiàn)ORM模型的方法詳解
訪問(wèn)或者修改描述器對(duì)象的屬性時(shí)無(wú)法觸發(fā)__setattr__等方法,只會(huì)觸發(fā)描述器類內(nèi)部的__set__,__get__,__delete__方法.
ORM模型:類名對(duì)應(yīng)表名,對(duì)象對(duì)應(yīng)的數(shù)據(jù)行,類屬性對(duì)應(yīng)數(shù)據(jù)行的各字段,有幾個(gè)表字段,就綁定幾個(gè)類屬性;往表中增加數(shù)據(jù)就是創(chuàng)建對(duì)象,每創(chuàng)建一個(gè)對(duì)象,就是增加一行數(shù)據(jù)記錄。
ORM框架的功能:
1.建立模型類和表之間的對(duì)應(yīng)關(guān)系,允許我們通過(guò)面向?qū)ο蟮姆绞讲僮鲾?shù)據(jù)庫(kù)。
2.根據(jù)設(shè)計(jì)的模型類生成數(shù)據(jù)庫(kù)中的表格。
3.通過(guò)方便的配置就可以進(jìn)行數(shù)據(jù)庫(kù)的切換。
MySql的常用數(shù)據(jù)類型:
1.整數(shù):int,bit
2.小數(shù):decimal(decimal表示浮點(diǎn)數(shù),decimal(5,2)表示共計(jì)5位數(shù),小數(shù)占2位)
3.字符串:varchar(可變長(zhǎng)度),char(不可變長(zhǎng)度)
4.日期時(shí)間:date,time,datetime
5.枚舉類型:enum
模型類案例:
"""
django的ORM模型字段
BooleanField: 布爾字段,True或False
CharField(max_length=最大長(zhǎng)度): 字符串,參數(shù)max_length表示最大字符個(gè)數(shù)
IntegerField: 整數(shù)
"""
class TestReport(BaseTable):
class Meat:
verbose_name = '測(cè)試報(bào)告'
db_table = "TestReport"
report_name = models.CharField(max_length=40, null=False)
start_at = models.CharField(max_length=40, null=True)
status = models.BooleanField()
testRun = models.IntegerField()
successes = models.IntegerField()
reports = models.TextField()1.__set__方法:設(shè)置屬性
"""
只要一個(gè)類中出現(xiàn)了:
__get__(self,instance,owner)
__set__(self,instance,value)
__delete__(self,instance)
__set_name__(self,owner,name)
中的任意一個(gè)方法,這個(gè)類就不是一個(gè)普通的類了,
應(yīng)被稱為:
描述器類(應(yīng)用在ORM模型中)
"""
class Field(object):
"""
只要一個(gè)類中出現(xiàn)了以下任意一個(gè)方法,這個(gè)類就是一個(gè)描述器類
"""
def __get__(self, instance, owner):
pass
def __set__(self, instance, value):
print('---set---方法被觸發(fā)了')
def __delete__(self, instance):
pass
class Model(object):
attr = Field() # attr是一個(gè)描述器對(duì)象,修改時(shí)無(wú)法觸發(fā)__setattr__等方法,
# 只能觸發(fā)描述器類內(nèi)部的__set__方法
if __name__ == '__main__':
m = Model()
m.attr = 666 # 嘗試修改attr屬性
print(m.attr)
# 輸出:
---set - --方法被觸發(fā)了
None
class Field(object):
"""
只要一個(gè)類中出現(xiàn)了以下任意一個(gè)方法,這個(gè)類就是一個(gè)描述器類
"""
def __get__(self, instance, owner):
pass
def __set__(self, instance, value):
"""
:param instance: 修改的對(duì)象
:param value: 修改的值
:return:
"""
print('---set---方法被觸發(fā)了')
self.value = value
print(self) # <__main__.Field object at 0x7fecc01f8a30>
print(instance) # <__main__.Model object at 0x7fecc01f8a00>
print(value) # 666
def __delete__(self, instance):
pass
class Model(object):
attr = Field() # attr是一個(gè)描述器對(duì)象,修改時(shí)無(wú)法觸發(fā)__setattr__等方法,
# 只能觸發(fā)描述器類內(nèi)部的__set__方法
if __name__ == '__main__':
m = Model()
print(m) # <__main__.Model object at 0x7fecc01f8a00>,與instance相同
m.attr = 666 # 嘗試修改attr屬性
2.__get__方法:訪問(wèn)屬性
"""
只要一個(gè)類中出現(xiàn)了:
__get__(self,instance,owner)
__set__(self,instance,value)
__delete__(self,instance)
__set_name__(self,owner,name)
中的任意一個(gè)方法,這個(gè)類就不是一個(gè)普通的類了,
應(yīng)被稱為:
描述器類(應(yīng)用在ORM模型中)
"""
class Field(object):
"""
只要一個(gè)類中出現(xiàn)了以下任意一個(gè)方法,這個(gè)類就是一個(gè)描述器類
"""
def __get__(self, instance, owner):
print('---get---方法被觸發(fā)了')
def __set__(self, instance, value):
"""
:param instance: 修改的對(duì)象
:param value: 修改的值
:return:
"""
print('---set---方法被觸發(fā)了')
self.value = value
def __delete__(self, instance):
pass
class Model(object):
attr = Field() # attr是一個(gè)描述器對(duì)象,修改時(shí)無(wú)法觸發(fā)__setattr__等方法,
# 只能觸發(fā)描述器類內(nèi)部的__set__方法
if __name__ == '__main__':
m = Model()
m.attr = 666 # 嘗試修改attr屬性
print(m.attr)
# 輸出:
---set - --方法被觸發(fā)了
---get - --方法被觸發(fā)了
None
"""
只要一個(gè)類中出現(xiàn)了:
__get__(self,instance,owner)
__set__(self,instance,value)
__delete__(self,instance)
__set_name__(self,owner,name)
中的任意一個(gè)方法,這個(gè)類就不是一個(gè)普通的類了,
應(yīng)被稱為:
描述器類(應(yīng)用在ORM模型中)
"""
class Field(object):
"""
只要一個(gè)類中出現(xiàn)了以下任意一個(gè)方法,這個(gè)類就是一個(gè)描述器類
"""
def __get__(self, instance, owner):
print('---get---方法被觸發(fā)了')
print(instance) # <__main__.Model object at 0x7f80b81a09d0>
print(owner) # <class '__main__.Model'>
return self.value
def __set__(self, instance, value):
"""
:param instance: 修改的對(duì)象
:param value: 修改的值
:return:
"""
print('---set---方法被觸發(fā)了')
self.value = value
def __delete__(self, instance):
pass
class Model(object):
attr = Field() # attr是一個(gè)描述器對(duì)象,修改時(shí)無(wú)法觸發(fā)__setattr__等方法,
# 只能觸發(fā)描述器類內(nèi)部的__set__方法
if __name__ == '__main__':
m = Model()
m.attr = 666 # 嘗試修改attr屬性
print(m.attr) # 666
# 輸出:
---set - --方法被觸發(fā)了
---get - --方法被觸發(fā)了
< __main__.Model object at 0x7f80b81a09d0 >
< class '__main__.Model'>
666
3.__delete__方法:刪除屬性
"""
只要一個(gè)類中出現(xiàn)了:
__get__(self,instance,owner)
__set__(self,instance,value)
__delete__(self,instance)
__set_name__(self,owner,name)
中的任意一個(gè)方法,這個(gè)類就不是一個(gè)普通的類了,
應(yīng)被稱為:
描述器類(應(yīng)用在ORM模型中)
"""
class Field(object):
"""
只要一個(gè)類中出現(xiàn)了以下任意一個(gè)方法,這個(gè)類就是一個(gè)描述器類
"""
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
"""
:param instance: 修改的對(duì)象
:param value: 修改的值
:return:
"""
print('---set---方法被觸發(fā)了')
self.value = value
def __delete__(self, instance):
print('---delete---方法被觸發(fā)了')
class Model(object):
attr = Field() # attr是一個(gè)描述器對(duì)象,修改時(shí)無(wú)法觸發(fā)__setattr__等方法,
# 只能觸發(fā)描述器類內(nèi)部的__set__方法
if __name__ == '__main__':
m = Model()
m.attr = 666 # 嘗試修改attr屬性
del m.attr # ---delete---方法被觸發(fā)了
print(m.attr) # None
# 輸出:
---set - --方法被觸發(fā)了
---delete - --方法被觸發(fā)了
666
"""
只要一個(gè)類中出現(xiàn)了:
__get__(self,instance,owner)
__set__(self,instance,value)
__delete__(self,instance)
__set_name__(self,owner,name)
中的任意一個(gè)方法,這個(gè)類就不是一個(gè)普通的類了,
應(yīng)被稱為:
描述器類(應(yīng)用在ORM模型中)
"""
class Field(object):
"""
只要一個(gè)類中出現(xiàn)了以下任意一個(gè)方法,這個(gè)類就是一個(gè)描述器類
"""
def __get__(self, instance, owner):
print('---get---方法被觸發(fā)了')
print(instance) # <__main__.Model object at 0x7f80b81a09d0>
print(owner) # <class '__main__.Model'>
return self.value
def __set__(self, instance, value):
"""
:param instance: 修改的對(duì)象
:param value: 修改的值
:return:
"""
print('---set---方法被觸發(fā)了')
self.value = value
def __delete__(self, instance):
print('---delete---方法被觸發(fā)了')
print(instance) # <__main__.Model object at 0x7ff61806a160>
self.value = None
class Model(object):
attr = Field() # attr是一個(gè)描述器對(duì)象,修改時(shí)無(wú)法觸發(fā)__setattr__等方法,
# 只能觸發(fā)描述器類內(nèi)部的__set__方法
if __name__ == '__main__':
m = Model()
m.attr = 666 # 嘗試修改attr屬性
del m.attr # ---delete---方法被觸發(fā)了
print(m.attr) # None
# 輸出:
---set - --方法被觸發(fā)了
---delete - --方法被觸發(fā)了
< __main__.Model object at 0x7ff61806a160 >
---get - --方法被觸發(fā)了
< __main__.Model object at 0x7ff61806a160 >
<class '__main__.Model'>
None
4.描述器實(shí)現(xiàn)ORM模型:
"""
通過(guò)描述器實(shí)現(xiàn)ORM模型
"""
class CharField(object):
def __init__(self,max_length=20):
self.max_length = max_length
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
# 首先判斷是否為空
if value is not None:
# 再判斷是否是字符串
if isinstance(value, str):
# 再判斷長(zhǎng)度是否符合要求
if len(value) <= self.max_length:
self.value = value
else:
raise TypeError('length need less than {}'.format(self.max_length))
else:
raise TypeError('need a str')
else:
raise TypeError("can not be None")
def __delete__(self, instance):
self.value = None
class IntegerField(object):
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
# 首先判斷是否為空
if value is not None:
# 再判斷是否是整數(shù)int
if isinstance(value, int):
self.value = value
else:
raise TypeError('need a int')
else:
raise TypeError("can not be None")
def __delete__(self, instance):
self.value = None
class UserModel(object):
# 定義用戶信息的模型類
name = CharField(max_length=20) # 定義:name只能賦值為字符串
pwd = CharField(max_length=40)
age = IntegerField() # 定義:age只能賦值為整數(shù)
if __name__ == '__main__':
user = UserModel()
user.name = "春田"
print(user.name) # 輸出: 春田
user.age = 130
print(user.age) # 輸出: 130
user.pwd = 'wsdgdgdrgerdsfs方式范德薩發(fā)阿瑟費(fèi)薩法 sfa fda fsdf sdf fg'
print(user.pwd) # 輸出: TypeError: length need less than 40
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
python代碼實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python代碼實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
Python實(shí)現(xiàn)發(fā)送帶有pdf附件的電子郵件
使用Python發(fā)郵件,是個(gè)簡(jiǎn)單的話題,可是如何可以優(yōu)雅的輕松的群發(fā)郵件,并附加PDF附件,是很多小伙伴的日常工作。本文就來(lái)和大家分享一下實(shí)現(xiàn)方法,需要的可以參考一下2023-02-02
用python寫(xiě)一個(gè)windows下的定時(shí)關(guān)機(jī)腳本(推薦)
由于本人經(jīng)常使用筆記本共享WiFi,但是又不想筆記本開(kāi)機(jī)一夜,每次都是使用dos命令關(guān)機(jī),感覺(jué)好麻煩,然后小編想到用python寫(xiě)一個(gè)定時(shí)關(guān)機(jī)的腳本,具體實(shí)例代碼請(qǐng)參考本文2017-03-03
selenium+python實(shí)現(xiàn)基本自動(dòng)化測(cè)試的示例代碼
這篇文章主要介紹了selenium+python實(shí)現(xiàn)基本自動(dòng)化測(cè)試的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
Flask-Docs自動(dòng)生成Api文檔安裝使用教程
這篇文章主要為大家介紹了Flask-Docs自動(dòng)生成Api文檔安裝使用教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
python實(shí)現(xiàn)局域網(wǎng)內(nèi)實(shí)時(shí)通信代碼
今天小編就為大家分享一篇python實(shí)現(xiàn)局域網(wǎng)內(nèi)實(shí)時(shí)通信代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-12-12
Python+Opencv身份證號(hào)碼區(qū)域提取及識(shí)別實(shí)現(xiàn)
這篇文章主要介紹了Python+Opencv身份證號(hào)碼區(qū)域提取及識(shí)別實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
python使用pandas讀寫(xiě)excel文件的方法實(shí)例
pandas是一個(gè)十分強(qiáng)大的數(shù)據(jù)處理工具,最近需要處理數(shù)據(jù)并輸入到excel,簡(jiǎn)單列舉它的用法,這篇文章主要給大家介紹了關(guān)于python使用pandas讀寫(xiě)excel文件的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08
一文詳解凱撒密碼的原理及Python實(shí)現(xiàn)
凱撒密碼是古羅馬愷撒大帝用來(lái)對(duì)軍事情報(bào)進(jìn)行加密的算法,它采用了替換方法對(duì)信息中的每一個(gè)英文字符循環(huán)替換為字母表序列該字符后面第三個(gè)字符。本文主要為大家講解了凱撒密碼的原理及實(shí)現(xiàn),需要的可以參考一下2022-08-08

