博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
元类编程-- 实现orm,以django Model为例
阅读量:5161 次
发布时间:2019-06-13

本文共 3731 字,大约阅读时间需要 12 分钟。

# 需求import numbersclass Field:    passclass IntField(Field):    # 数据描述符    def __init__(self, db_column, min_value=None, max_value=None):        self._value = None        self.min_value = min_value        self.max_value = max_value        self.db_column = db_column        if min_value is not None:            if not isinstance(min_value, numbers.Integral):                raise ValueError("min_value must be int")            elif min_value < 0:                raise ValueError("min_value must be positive int")        if max_value is not None:            if not isinstance(max_value, numbers.Integral):                raise ValueError("max_value must be int")            elif max_value < 0:                raise ValueError("max_value must be positive int")        if min_value is not None and max_value is not None:            if min_value > max_value:                raise ValueError("min_value must be smaller than max_value")    def __get__(self, instance, owner):        return self._value    def __set__(self, instance, value):        if not isinstance(value, numbers.Integral):            raise ValueError("int value need")        if value < self.min_value or value > self.max_value:            raise ValueError("value must between min_value and max_value")        self._value = valueclass CharField(Field):    def __init__(self, db_column, max_length=None):        self._value = None        self.db_column = db_column        if max_length is None:            raise ValueError("you must spcify max_lenth for charfiled")        self.max_length = max_length    def __get__(self, instance, owner):        return self._value    def __set__(self, instance, value):        if not isinstance(value, str):            raise ValueError("string value need")        if len(value) > self.max_length:            raise ValueError("value len excess len of max_length")        self._value = valueclass ModelMetaClass(type):    def __new__(cls, name, bases, attrs, **kwargs):        if name == "BaseModel":            return super().__new__(cls, name, bases, attrs, **kwargs)        fields = {}        for key, value in attrs.items():            if isinstance(value, Field):                fields[key] = value        attrs_meta = attrs.get("Meta", None)        _meta = {}        db_table = name.lower()        if attrs_meta is not None:            table = getattr(attrs_meta, "db_table", None)            if table is not None:                db_table = table        _meta["db_table"] = db_table        attrs["_meta"] = _meta        attrs["fields"] = fields        del attrs["Meta"]        return super().__new__(cls, name, bases, attrs, **kwargs)class BaseModel(metaclass=ModelMetaClass):    def __init__(self, *args, **kwargs):        for key, value in kwargs.items():            setattr(self, key, value)        return super().__init__()    def save(self):        fields = []        values = []        for key, value in self.fields.items():            db_column = value.db_column            if db_column is None:                db_column = key.lower()            fields.append(db_column)            value = getattr(self, key)            values.append(str(value))        sql = "insert {db_table}({fields}) value({values})".format(db_table=self._meta["db_table"],                                                                   fields=",".join(fields), values=",".join(values))        passclass User(BaseModel):    name = CharField(db_column="name", max_length=10)    age = IntField(db_column="age", min_value=1, max_value=100)    class Meta:        db_table = "user"if __name__ == "__main__":    user = User(name="erick", age=28)    # user.name = "erick"    # user.age = 28    user.save()

 

转载于:https://www.cnblogs.com/Erick-L/p/8884333.html

你可能感兴趣的文章
心急的C小加
查看>>
编译原理 First,Follow,select集求法
查看>>
(一一二)图文混排中特殊文字的点击与事件处理
查看>>
iPhone开发经典语录集锦 (转)
查看>>
SVM基础必备常识
查看>>
FPGA时序约束的几种方法 (转)
查看>>
cocos2dx 3.x tolua 分析
查看>>
oracle 外网访问
查看>>
jdbc连接数据库方式问题
查看>>
一步一回头撞在了南墙上
查看>>
POJ2965 The Pilots Brothers' refrigerator
查看>>
C# 2.0 中的新增功能01 分布类与分部方法
查看>>
关于腾讯ip接口一个流传很广的错误用法
查看>>
java 浅拷贝和深拷贝
查看>>
unity如何判断应用的运行平台
查看>>
LAMMPS脚本1
查看>>
Kubernetes 1.10.4 镜像 版本
查看>>
[每天进步一点 -- 流水账]回顾总结
查看>>
[小明学算法]6.字符串匹配算法---KMP
查看>>
url的处理
查看>>