Python使用描述器实现ORM模型的方法详解
短信预约 -IT技能 免费直播动态提醒
访问或者修改描述器对象的属性时无法触发__setattr__等方法,只会触发描述器类内部的__set__,__get__,__delete__方法.
ORM模型:类名对应表名,对象对应的数据行,类属性对应数据行的各字段,有几个表字段,就绑定几个类属性;往表中增加数据就是创建对象,每创建一个对象,就是增加一行数据记录。
ORM框架的功能:
1.建立模型类和表之间的对应关系,允许我们通过面向对象的方式操作数据库。
2.根据设计的模型类生成数据库中的表格。
3.通过方便的配置就可以进行数据库的切换。
MySql的常用数据类型:
1.整数:int,bit
2.小数:decimal(decimal表示浮点数,decimal(5,2)表示共计5位数,小数占2位)
3.字符串:varchar(可变长度),char(不可变长度)
4.日期时间:date,time,datetime
5.枚举类型:enum
模型类案例:
"""
django的ORM模型字段
BooleanField: 布尔字段,True或False
CharField(max_length=最大长度): 字符串,参数max_length表示最大字符个数
IntegerField: 整数
"""
class TestReport(BaseTable):
class Meat:
verbose_name = '测试报告'
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__方法:设置属性
"""
只要一个类中出现了:
__get__(self,instance,owner)
__set__(self,instance,value)
__delete__(self,instance)
__set_name__(self,owner,name)
中的任意一个方法,这个类就不是一个普通的类了,
应被称为:
描述器类(应用在ORM模型中)
"""
class Field(object):
"""
只要一个类中出现了以下任意一个方法,这个类就是一个描述器类
"""
def __get__(self, instance, owner):
pass
def __set__(self, instance, value):
print('---set---方法被触发了')
def __delete__(self, instance):
pass
class Model(object):
attr = Field() # attr是一个描述器对象,修改时无法触发__setattr__等方法,
# 只能触发描述器类内部的__set__方法
if __name__ == '__main__':
m = Model()
m.attr = 666 # 尝试修改attr属性
print(m.attr)
# 输出:
---set - --方法被触发了
None
class Field(object):
"""
只要一个类中出现了以下任意一个方法,这个类就是一个描述器类
"""
def __get__(self, instance, owner):
pass
def __set__(self, instance, value):
"""
:param instance: 修改的对象
:param value: 修改的值
:return:
"""
print('---set---方法被触发了')
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是一个描述器对象,修改时无法触发__setattr__等方法,
# 只能触发描述器类内部的__set__方法
if __name__ == '__main__':
m = Model()
print(m) # <__main__.Model object at 0x7fecc01f8a00>,与instance相同
m.attr = 666 # 尝试修改attr属性
2.__get__方法:访问属性
"""
只要一个类中出现了:
__get__(self,instance,owner)
__set__(self,instance,value)
__delete__(self,instance)
__set_name__(self,owner,name)
中的任意一个方法,这个类就不是一个普通的类了,
应被称为:
描述器类(应用在ORM模型中)
"""
class Field(object):
"""
只要一个类中出现了以下任意一个方法,这个类就是一个描述器类
"""
def __get__(self, instance, owner):
print('---get---方法被触发了')
def __set__(self, instance, value):
"""
:param instance: 修改的对象
:param value: 修改的值
:return:
"""
print('---set---方法被触发了')
self.value = value
def __delete__(self, instance):
pass
class Model(object):
attr = Field() # attr是一个描述器对象,修改时无法触发__setattr__等方法,
# 只能触发描述器类内部的__set__方法
if __name__ == '__main__':
m = Model()
m.attr = 666 # 尝试修改attr属性
print(m.attr)
# 输出:
---set - --方法被触发了
---get - --方法被触发了
None
"""
只要一个类中出现了:
__get__(self,instance,owner)
__set__(self,instance,value)
__delete__(self,instance)
__set_name__(self,owner,name)
中的任意一个方法,这个类就不是一个普通的类了,
应被称为:
描述器类(应用在ORM模型中)
"""
class Field(object):
"""
只要一个类中出现了以下任意一个方法,这个类就是一个描述器类
"""
def __get__(self, instance, owner):
print('---get---方法被触发了')
print(instance) # <__main__.Model object at 0x7f80b81a09d0>
print(owner) # <class '__main__.Model'>
return self.value
def __set__(self, instance, value):
"""
:param instance: 修改的对象
:param value: 修改的值
:return:
"""
print('---set---方法被触发了')
self.value = value
def __delete__(self, instance):
pass
class Model(object):
attr = Field() # attr是一个描述器对象,修改时无法触发__setattr__等方法,
# 只能触发描述器类内部的__set__方法
if __name__ == '__main__':
m = Model()
m.attr = 666 # 尝试修改attr属性
print(m.attr) # 666
# 输出:
---set - --方法被触发了
---get - --方法被触发了
< __main__.Model object at 0x7f80b81a09d0 >
< class '__main__.Model'>
666
3.__delete__方法:删除属性
"""
只要一个类中出现了:
__get__(self,instance,owner)
__set__(self,instance,value)
__delete__(self,instance)
__set_name__(self,owner,name)
中的任意一个方法,这个类就不是一个普通的类了,
应被称为:
描述器类(应用在ORM模型中)
"""
class Field(object):
"""
只要一个类中出现了以下任意一个方法,这个类就是一个描述器类
"""
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
"""
:param instance: 修改的对象
:param value: 修改的值
:return:
"""
print('---set---方法被触发了')
self.value = value
def __delete__(self, instance):
print('---delete---方法被触发了')
class Model(object):
attr = Field() # attr是一个描述器对象,修改时无法触发__setattr__等方法,
# 只能触发描述器类内部的__set__方法
if __name__ == '__main__':
m = Model()
m.attr = 666 # 尝试修改attr属性
del m.attr # ---delete---方法被触发了
print(m.attr) # None
# 输出:
---set - --方法被触发了
---delete - --方法被触发了
666
"""
只要一个类中出现了:
__get__(self,instance,owner)
__set__(self,instance,value)
__delete__(self,instance)
__set_name__(self,owner,name)
中的任意一个方法,这个类就不是一个普通的类了,
应被称为:
描述器类(应用在ORM模型中)
"""
class Field(object):
"""
只要一个类中出现了以下任意一个方法,这个类就是一个描述器类
"""
def __get__(self, instance, owner):
print('---get---方法被触发了')
print(instance) # <__main__.Model object at 0x7f80b81a09d0>
print(owner) # <class '__main__.Model'>
return self.value
def __set__(self, instance, value):
"""
:param instance: 修改的对象
:param value: 修改的值
:return:
"""
print('---set---方法被触发了')
self.value = value
def __delete__(self, instance):
print('---delete---方法被触发了')
print(instance) # <__main__.Model object at 0x7ff61806a160>
self.value = None
class Model(object):
attr = Field() # attr是一个描述器对象,修改时无法触发__setattr__等方法,
# 只能触发描述器类内部的__set__方法
if __name__ == '__main__':
m = Model()
m.attr = 666 # 尝试修改attr属性
del m.attr # ---delete---方法被触发了
print(m.attr) # None
# 输出:
---set - --方法被触发了
---delete - --方法被触发了
< __main__.Model object at 0x7ff61806a160 >
---get - --方法被触发了
< __main__.Model object at 0x7ff61806a160 >
<class '__main__.Model'>
None
4.描述器实现ORM模型:
"""
通过描述器实现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):
# 再判断长度是否符合要求
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:
# 再判断是否是整数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只能赋值为整数
if __name__ == '__main__':
user = UserModel()
user.name = "春田"
print(user.name) # 输出: 春田
user.age = 130
print(user.age) # 输出: 130
user.pwd = 'wsdgdgdrgerdsfs方式范德萨发阿瑟费萨法 sfa fda fsdf sdf fg'
print(user.pwd) # 输出: TypeError: length need less than 40
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341