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