-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodels.py
208 lines (184 loc) · 5.68 KB
/
models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
import json
from utils import log
def save(data, path):
"""
data 是 dict 或者 list
path 是保存文件的路径
"""
s = json.dumps(data, indent=2, ensure_ascii=False)
with open(path, 'w+', encoding='utf-8') as f:
# log('save', path, s, data)
f.write(s)
def load(path):
with open(path, 'r', encoding='utf-8') as f:
s = f.read()
# log('load', s)
return json.loads(s)
class Model(object):
"""
Model 是所有 model 的基类
@classmethod 是一个套路用法
例如
user = User()
user.db_path() 返回 User.txt
"""
@classmethod
def db_path(cls):
"""
cls 是类名, 谁调用的类名就是谁的
classmethod 有一个参数是 class(这里我们用 cls 这个名字)
所以我们可以得到 class 的名字
"""
classname = cls.__name__
path = '{}.txt'.format(classname)
return path
@classmethod
def all(cls):
"""
all 方法(类里面的函数叫方法)使用 load 函数得到所有的 models
"""
path = cls.db_path()
models = load(path)
# 这里用了列表推导生成一个包含所有 实例 的 list
# m 是 dict, 用 cls.new(m) 可以初始化一个 cls 的实例
# 不明白就 log 大法看看这些都是啥
ms = [cls.new(m) for m in models]
return ms
@classmethod
def new(cls, form):
m = cls(form)
return m
@classmethod
def find_by(cls, **kwargs):
"""
用法如下,kwargs 是只有一个元素的 dict
u = User.find_by(username='gua')
"""
log('kwargs, ', kwargs)
k, v = '', ''
for key, value in kwargs.items():
k, v = key, value
all = cls.all()
for m in all:
# getattr(m, k) 等价于 m.__dict__[k]
if v == m.__dict__[k]:
return m
return None
@classmethod
def find_all(cls, **kwargs):
"""
用法如下,kwargs 是只有一个元素的 dict
u = User.find_by(username='gua')
"""
log('kwargs, ', kwargs)
k, v = '', ''
for key, value in kwargs.items():
k, v = key, value
all = cls.all()
data = []
for m in all:
# getattr(m, k) 等价于 m.__dict__[k]
if v == m.__dict__[k]:
data.append(m)
return data
def __repr__(self):
"""
__repr__ 是一个魔法方法
简单来说, 它的作用是得到类的 字符串表达 形式
比如 print(u) 实际上是 print(u.__repr__())
"""
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)
def save(self):
"""
用 all 方法读取文件中的所有 model 并生成一个 list
把 self 添加进去并且保存进文件
"""
log('debug save')
models = self.all()
log('models', models)
first_index = 0
if self.__dict__.get('id') is None:
# 加上 id
if len(models) > 3:
log('用 log 可以查看代码执行的走向')
# 不是第一个数据
self.id = models[-1].id + 1
else:
# 是第一个数据
log('first index', first_index)
self.id = first_index
models.append(self)
else:
# 有 id 说明已经是存在于数据文件中的数据
# 那么就找到这条数据并替换之
index = -1
for i, m in enumerate(models):
if m.id == self.id:
index = i
break
# 看看是否找到下标
# 如果找到,就替换掉这条数据
if index > -1:
models[index] = self
# 保存
l = [m.__dict__ for m in models]
path = self.db_path()
save(l, path)
class User(Model):
"""
User 是一个保存用户数据的 model
现在只有两个属性 username 和 password
"""
def __init__(self, form):
self.id = form.get('id', None)
if self.id is not None:
self.id = int(self.id)
self.username = form.get('username', '')
self.password = form.get('password', '')
def validate_login(self):
# return self.username == 'gua' and self.password == '123'
u = User.find_by(username=self.username)
# us = User.all()
# for u in us:
# if u.username == self.username and u.password == self.password:
# return True
# return False
return u is not None and u.password == self.password
# 这样的代码是不好的,不应该用隐式转换
# return u and u.password == self.password
"""
0 None ''
"""
def validate_register(self):
return len(self.username) > 2 and len(self.password) > 2
class Message(Model):
"""
Message 是用来保存留言的 model
"""
def __init__(self, form):
self.author = form.get('author', '')
self.message = form.get('message', '')
def test():
users = User.all()
log(users)
# u = User.find_by(username='gua')
# log('users', u)
# form = dict(
# username='gua',
# password='gua',
# )
# u = User(form)
# u.save()
# u.save()
# u.save()
# u.save()
# u.save()
# u.save()
# u = User.find_by(id=1)
# u.username = '瓜'
# u.save()
if __name__ == '__main__':
test()