博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python ORM 模块peewee(四): Model类源码初探
阅读量:5238 次
发布时间:2019-06-14

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

Model的初始化方法主要继承自BaseModel类的__new__方法。 下面粗略的通过源码来看看:

class BaseModel(type):    # 定义可被继承的属性列表(全局)    inheritable = set([        'constraints', 'database', 'db_table_func', 'indexes', 'order_by',        'primary_key', 'schema', 'validate_backrefs', 'only_save_dirty'])    def __new__(cls, name, bases, attrs):        # 如果没有父类,则之间创建BaseModel类        if not bases:            return super(BaseModel, cls).__new__(cls, name, bases, attrs)        # Meta类的属性通过meta_options存储在Model类中        meta_options = {}                # 将Meta从属性中移除,将Meta中的非私有属性加入meta_options中        meta = attrs.pop('Meta', None)        if meta:            for k, v in meta.__dict__.items():                if not k.startswith('_'):                    meta_options[k] = v        # 从meta中获取主键信息        model_pk = getattr(meta, 'primary_key', None)        parent_pk = None        ############################################################        # 开始考虑从父类中继承的情况        #############################################################        for b in bases:            if not hasattr(b, '_meta'):                continue            base_meta = getattr(b, '_meta')            if parent_pk is None:                parent_pk = deepcopy(base_meta.primary_key)            all_inheritable = cls.inheritable | base_meta._additional_keys            # 获取父类中的Meta内部类字段,只考虑all_inheritable中的字段            for (k, v) in base_meta.__dict__.items():                if k in all_inheritable and k not in meta_options:                    meta_options[k] = v                                 # 获取父类中的Fields, 即表的字段            for (k, v) in b.__dict__.items():                if k in attrs:                    continue                if isinstance(v, FieldDescriptor):                    if not v.field.primary_key:                        attrs[k] = deepcopy(v.field)        # initialize the new class and set the magic attributes        cls = super(BaseModel, cls).__new__(cls, name, bases, attrs)        ModelOptionsBase = meta_options.get('model_options_base', ModelOptions)        cls._meta = ModelOptionsBase(cls, **meta_options)        cls._data = None        cls._meta.indexes = list(cls._meta.indexes)        # 默认表名的设定,Model名的小写,然后将非数字和英文字符换成'_'        if not cls._meta.db_table:            cls._meta.db_table = re.sub('[^\w]+', '_', cls.__name__.lower())        # replace fields with field descriptors, calling the add_to_class hook        # 这里筛选attr中的Field类型字段,设置Model中的数据类型        # 也许可以测试一下类里面的函数是怎么继承的        fields = []        for name, attr in cls.__dict__.items():            if isinstance(attr, Field):                if attr.primary_key and model_pk:                    raise ValueError('primary key is overdetermined.')                elif attr.primary_key:                    model_pk, pk_name = attr, name                else:                    fields.append((attr, name))                composite_key = False        # 默认主键的设置,如果无法从父类继承,,则使用'id'为key, 也就是行号        if model_pk is None:            if parent_pk:                model_pk, pk_name = parent_pk, parent_pk.name            else:                model_pk, pk_name = PrimaryKeyField(primary_key=True), 'id'        elif isinstance(model_pk, CompositeKey):            pk_name = '_composite_key'            composite_key = True        # 如果model本身有主键的情况        if model_pk is not False:            model_pk.add_to_class(cls, pk_name)            cls._meta.primary_key = model_pk            cls._meta.auto_increment = (                isinstance(model_pk, PrimaryKeyField) or                bool(model_pk.sequence))            cls._meta.composite_key = composite_key        # 设置Fields        for field, name in fields:            field.add_to_class(cls, name)        # create a repr and error class before finalizing        # __unicode__的设置        if hasattr(cls, '__unicode__'):            setattr(cls, '__repr__', lambda self: '<%s: %r>' % (                cls.__name__, self.__unicode__()))        # 错误信息        exc_name = '%sDoesNotExist' % cls.__name__        exc_attrs = {'__module__': cls.__module__}        exception_class = type(exc_name, (DoesNotExist,), exc_attrs)        cls.DoesNotExist = exception_class        cls._meta.prepared()        if hasattr(cls, 'validate_model'):            cls.validate_model()        return cls

转载于:https://www.cnblogs.com/noway-neway/p/5276527.html

你可能感兴趣的文章
【kindle】【转发】kindle链接WIFI自动断开问题
查看>>
ios storyboard全解析 (一)
查看>>
caffe卷积层实现
查看>>
变量及简单数据类型
查看>>
存储过程 函数
查看>>
选择排序
查看>>
python文件指针--seek
查看>>
个人总结
查看>>
【P2236】彩票(搜索+剪枝)
查看>>
第三次小组实践作业小组每日进度汇报:2017-12-4
查看>>
设计模式之单例模式
查看>>
关于网络安全的一些思考
查看>>
数据库和集合
查看>>
数组排序 block排序 和数组内排序
查看>>
Linux之-命令
查看>>
CSS中强大的EM
查看>>
前序,中序,后序问题
查看>>
计算属性和监听,computed,watch
查看>>
队列的实现
查看>>
Spring Boot入门
查看>>