美文网首页
Model(orm)(3)

Model(orm)(3)

作者: 马梦里 | 来源:发表于2017-12-18 19:07 被阅读0次

Model

class Model(object):
    def __init__(self, form):
        self.id = form.get('id', None)

Model为数据的基类,以后数据的建立都基于此,比如UserCommentWeiboSession等。
__init__ 方法定义类的属性,参数 form 是一个字典

    @classmethod
    def db_path(cls):
        classname = cls.__name__
        path = '{}.txt'.format(classname)
        return path

有装饰器@classmethod的称为类方法,第一个参数为cls,可以直接调用;
普通方法的第一个参数为self,必须经过实例化后才能调用;
__name__ 属性能够返回类的名字,这个类方法的意义在于返回一个以类名字命名的text文件;

    @classmethod
    def new(cls, form):
        m = cls(form)
        return m

该方法等价于Model(form),调用的__init__(form)方法,也就是实例化一个对象,只是为了增加辨识性(增);

    @classmethod
    def all(cls):
        path = cls.db_path()
        models = load(path)
        ms = [cls.new(m) for m in models]
        return ms

同一个类下面的方法可以相互调用,all()方法获取所有的实例,组成一个列表(原始数据结构是属性结构,非字典结构,通过魔法函数改造后,才成了字典结构)。这里调用 new() 方法是为了获得类的数据结构,因为存储的数据结构和类的数据结构不一样:

存储在txt文件里的数据结构.png 类的数据结构.png
    @classmethod
    def find_by(cls, **kwargs):
        users = cls.all()
        for user in users:
            for key, value in kwargs.items():
                if hasattr(user, key) and value == getattr(user, key):
                    return user
        return None

这个类方法的作用是通过某个属性和值,获取对应的实例;
hasattr(objecrt, name):判断对象是否有name属性,返回值为 TrueFalse
getattr(object, name):表示获取对象name属性的值;
这里需要用户名(如果想通过用户名查找的话,这里返回的是相同用户名的第一个实例)和id唯一;
这里不能用 else,因为第一个不匹配的话,就直接else退出了。要遍历所有数据不能用 else

    def find_all(self, **kwargs):
        users = self.all()
        pass_word = ''
        for key in kwargs:
            pass_word = kwargs[key]
        user_list = []
        for user in users:
            if pass_word == getattr(user, 'password'):
                user_list.append(user)
        return user_list

找到具有共同属性的所有实例,一对多的时候需求较多;

    def save(self):
        models = self.all()
        if self.id is None:
            if len(models) == 0:
                self.id = 1
            else:
                self.id = models[-1].id + 1
        else:
            for i, m in enumerate(models):
                if m.id == self.id:
                    models[i] = self
        models.append(self)
        l = [m.__dict__ for m in models]
        path = self.db_path()
        save(l, path)

对第二个 else 的意义不是很了解;
最后三行,是将类的属性结构转换为字典结构,再储存在数据库中,不能实例直接存储

    def __repr__(self):
        classname = self.__class__.__name__
        properties = ['{}: ({})'.format(k, v) for k, v in self.__dict__.items()]
        s = '\n'.join(properties)
        return '< {}\n{} >\n'.format(classname, s)

这是个魔法函数,不需要调用,实例化时,就会自动运行,相当于自定义部分,根据自己的需求改变类的数据结构。
__class__:拿到当前的类,再获取类的名字;

str.join():拼接
'-'.join('a', 'b', 'c')
a-b-c

s = '\n'.join(properties):键值对之间换行
return '< {}\n{} >\n'.format(classname, s):类名和字典的换行;

u = User.new(form)
u
repr(u)
u.__repr__()
后面这三个等价

  1. 这是去掉魔法函数之后,类的数据结构
类的数据结构.png 类的数据结构.png
  1. 这是有魔法函数,类的数据结构
图片.png

这是去掉 join() 方法后,类的数据结构

图片.png

数据存储结构一直没变:

数据存储的结构.png
  1. 类的原始属性:
    __name__:类名
    __dict__:将树形结构转化为字典结构

Database

Json是一种轻量级的数据交互格式,易于人们阅读和编写。利用其dumps(序列化:将数组转化为 json 字符串)方法,可以将数据转化为所有程序都认识的字符串,并写入文件。loads(反序列化:将json格式字符串转换为 python 格式字符串 str)方法将 json 编码的字符串转化为 python 的数据结构。
数据的存储与读取:

def save(data, path):
    s = json.dumps(data, indent=2, ensure_ascii=False)
    with open(path, 'w+', encoding='utf-8') as f:
        f.write(s)

json 就是一种数据格式,和 str 类似,json 格式的字符串交互好一点。
json.dumps() 的作用是将 data 转换为 json 字符串,缩进两个字符,并且对中文友好;
文件只能存字符串,所以需要转换;

def load(path):
    with open(path, 'r', encoding='utf-8') as f:
        s = f.read()
        log('load', s)
        return json.loads(s)

子类

class User(Model):
    def __init__(self, form):
        super().__init__(form)
        self.username = form.get('username', '')
        self.password = form.get('password', '')

    def validate_login(self):
        u = User.find_by(username = self.username)
        if u is not None and u.password == self.password:
            self.id = u.id
            return True
        else:
            return False

    def validate_register(self):
        return len(self.username) > 2 and len(self.password) > 2

继承基类的属性:
super.__init__(form)

相关文章

网友评论

      本文标题:Model(orm)(3)

      本文链接:https://www.haomeiwen.com/subject/fggmwxtx.html