Discuss / Python / 这一节的内容我看了两天,你们敢信...

这一节的内容我看了两天,你们敢信...

Topic source

不知道有没有人和我一样,看得稀里糊涂的... 我想说的是,如果一开始把我们要干嘛讲明白,就会好理解很多,不然根本不理解我们为什么要这么做,我们到底在做什么。 对于没有数据库基础的我来说,理解起来确实比较困难,所以只能从代码本身入手。 下面的文字我期望是稍微弄懂了老师的代码再继续往下看。 先看我们的目标:

class User(Model):
    # 定义类的属性到列的映射:
    id = IntegerField('id')
    name = StringField('username')
    email = StringField('email')
    password = StringField('password')

# 创建一个实例:
u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd')
# 保存到数据库:
u.save()

到底要做什么?其实做的就是,把name='Michael'转换成成username='Michael'等等。我们输入这句话时:

u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd')

其实就相当于对User这个字典的子类添加了四个item。然后我们要通过之前类User定义时的一些映射,来把四个item中的id,name,email,pwssword映射到id,username,email,pwssword,然后插入数据库中。也就是产生下面的输出:

SQL: insert into User (id,name,email,password) values (?,?,?,?)
ARGS: [12345, 'Michael', 'test@orm.org', 'my-pwd']

那我们最核心的Metaclass做了什么? 它在接收到下面的代码时:

class User(Model):
    # 定义类的属性到列的映射:
    id = IntegerField('id')
    name = StringField('username')
    email = StringField('email')
    password = StringField('password')

并不会产生4个新的属性,而是把这四个属性以key_value的形式储存到一个叫做__mapping__dict中,同时会把这些属性从attr中删掉,所以在调用type__new__()方法时就不会有这些属性了~同时还生成了一个叫__table__的属性,用来储存我们的表名。

然后呢?可以干嘛 然后,我们就可以在类Model里写一个save()方法,它会对我们实例里的所有item(不要忘记Model是继承dict,它本身是可以储存键值对的),把item里的key__mapping__里的映射找出来,然后输出对应的sql语句。

还有不会的? 对,我当时其实是被另外的代码难倒了...回想起来实在太好笑...

class Model(dict, metaclass=ModelMetaclass):

    def __init__(self, **kw):
        super(Model, self).__init__(**kw)

    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError:
            raise AttributeError(r"'Model' object has no attribute '%s'" % key)

    def __setattr__(self, key, value):
        self[key] = value

    def save(self):
        fields = []
        params = []
        args = []
        for k, v in self.__mappings__.items():
            fields.append(v.name)
            params.append('?')
            args.append(getattr(self, k, None))
        sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join(params))
        print('SQL: %s' % sql)
        print('ARGS: %s' % str(args))

这里面的__getattr__()__setattr__()有什么用???我的天,当时看了半天... 其实它们就是帮助你来获取Model里的元素的,加上这两个函数后,你可以使用xx.key来获取元素,也可以用getattr(xx,key)来获取元素。 所以,不要这两个函数,好像也是可以的...只要后面有个地方稍微改一下就好了... 至于是哪里,自己找去吧哈哈哈。

上面有一行写错啦~ 应该是:

SQL: insert into User (password,email,username,id) values (?,?,?,?)
ARGS: ['my-pwd', 'test@orm.org', 'Michael', 12345]

才对


  • 1

Reply