def all(cls, **kwargs): # SELECT * FROM User WHERE username='******' AND password='******' sql_select = 'SELECT * FROM {}'.format(cls.table_name()) if len(kwargs) > 0: sql_where = ' AND '.join( ['`{}`=%s'.format(k) for k in kwargs.keys()]) sql_select = '{} WHERE {}'.format(sql_select, sql_where) log('ORM all <{}>'.format(sql_select)) values = tuple(kwargs.values()) connection = cls._pymysql_connection() try: with connection.cursor() as cursor: log('ORM execute <{}>'.format( cursor.mogrify(sql_select, values))) cursor.execute(sql_select, values) result = cursor.fetchall() finally: connection.close() ms = [] for row in result: m = cls(row) ms.append(m) return ms
def f(request): log('comment_or_weibo_owner_required') if request.method == 'GET': data = request.query elif request.method == 'POST': data = request.form() else: raise ValueError('不支持的方法', request.method) comment_key = 'comment_id' weibo_key = 'weibo_id' if comment_key in data: c = Comment.one(id=int(data[comment_key])) if c is None: return redirect('/weibo/index') else: user_id = c.user_id elif weibo_key in data: w = Weibo.one(id=int(data[weibo_key])) if w is None: return redirect('/weibo/index') else: user_id = w.user_id else: raise ValueError('不支持的参数', data) u = current_user(request) if user_id == u.id: log('不是评论或者微博的作者', user_id, u.id) return route_function(request) else: return redirect('/weibo/index')
def update(cls, id, **kwargs): # UPDATE # `User` # SET # `username`=%s, `password`=%s # WHERE `id`=%s; sql_set = ', '.join(['`{}`=%s'.format(k) for k in kwargs.keys()]) sql_update = 'UPDATE {} SET {} WHERE `id`=%s'.format( cls.table_name(), sql_set, ) log('ORM update <{}>'.format(sql_update.replace('\n', ' '))) values = list(kwargs.values()) values.append(id) values = tuple(values) connection = cls._pymysql_connection() try: with connection.cursor() as cursor: log('ORM execute <{}>'.format( cursor.mogrify(sql_update, values))) cursor.execute(sql_update, values) connection.commit() finally: connection.close()
def insert(cls, form: typing.Dict[str, str]): # INSERT INTO # `user` (`username`, `password`, `email`) # VALUES # (`gua`, `123`, `[email protected]`) connection = cls._pymysql_connection() try: sql_keys = [] sql_values = [] for k in form.keys(): sql_keys.append('`{}`'.format(k)) sql_values.append('%s') formatted_sql_keys = ', '.join(sql_keys) formatted_sql_values = ', '.join(sql_values) sql_insert = 'INSERT INTO `{}` ({}) VALUES ({});'.format( cls.table_name(), formatted_sql_keys, formatted_sql_values) log('ORM insert <{}>'.format(sql_insert)) values = tuple(form.values()) with connection.cursor() as cursor: log('ORM execute <{}>'.format( cursor.mogrify(sql_insert, values))) cursor.execute(sql_insert, values) # 避免和内置函数 id 重名,所以用 _id _id = cursor.lastrowid connection.commit() finally: connection.close() # 先 commit,再关闭链接,再返回 return _id
def f(request): log('login_required', route_function) u = current_user(request) if u.is_guest(): log('login_required is_guest', u) return redirect('/login/view') else: return route_function(request)
def find_by(cls, **kwargs): log('find_by kwargs', kwargs) for m in cls.all(): exist = True for k, v in kwargs.items(): if not hasattr(m, k) or not getattr(m, k) == v: exist = False if exist: return m
def update(request): """ 用于增加新 todo 的路由函数 """ form = request.form() log('todo update', form, form['id'], type(form['id'])) todo_id = int(form['id']) Todo.update(todo_id, title=form['title']) # 浏览器发送数据过来被处理后, 重定向到首页 # 浏览器在请求新首页的时候, 就能看到新增的数据了 return redirect('/todo/index')
def all(cls): """ all 方法(类里面的函数叫方法)使用 load 函数得到所有的 models """ path = cls.db_path() models = load(path) log('models in all', models) # 这里用了列表推导生成一个包含所有 实例 的 list # m 是 dict, 用 cls.new(m) 可以初始化一个 cls 的实例 # 不明白就 log 大法看看这些都是啥 ms = [cls(m) for m in models] return ms
def delete(cls, id): sql_delete = 'DELETE FROM {} WHERE `id`=%s'.format(cls.table_name()) log('ORM delete <{}>'.format(sql_delete)) connection = cls._pymysql_connection() try: with connection.cursor() as cursor: log('ORM execute <{}>'.format( cursor.mogrify(sql_delete, (id, )))) cursor.execute(sql_delete, (id, )) connection.commit() finally: connection.close()
def f(request): log('same_user_required', route_function) u = current_user(request) if request.method == 'GET': todo_id = int(request.query['id']) elif request.method == 'POST': todo_id = int(request.form()['id']) else: raise ValueError('不支持的请求方法', request.method) t = Todo.one(id=todo_id) if t.user_id == u.id: return route_function(request) else: return redirect('/todo')
def f(request): log('comment_owner_required') u = current_user(request) id_key = 'comment_id' if id_key in request.query: comment_id = request.query[id_key] else: comment_id = request.form()[id_key] c = Comment.one(id=int(comment_id)) if c.user_id == u.id: log('不是评论作者', c) return route_function(request) else: return redirect('/weibo/index')
def f(request): log('weibo_owner_required') u = current_user(request) id_key = 'weibo_id' if id_key in request.query: weibo_id = request.query[id_key] else: weibo_id = request.form()[id_key] w = Weibo.one(id=int(weibo_id)) if w.user_id == u.id: log('不是微博作者', w) return route_function(request) else: return redirect('/weibo/index')
def find_all(cls, **kwargs): log('find_all kwargs', kwargs) models = [] for m in cls.all(): exist = True for k, v in kwargs.items(): log('for loop in find all', m, k, v, hasattr(m, k), getattr(m, k), getattr(m, k) == v) if not hasattr(m, k) or not getattr(m, k) == v: exist = False if exist: models.append(m) return models
def save(self): """ 用 all 方法读取文件中的所有 model 并生成一个 list 把 self 添加进去并且保存进文件 """ models = self.all() log('models', models) if self.id is None: # 加上 id if len(models) > 0: log('不是第一个元素', models[-1].id) self.id = models[-1].id + 1 else: log('第一个元素') self.id = 0 models.append(self) else: # 有 id 说明已经是存在于数据文件中的数据 # 那么就找到这条数据并替换 for i, m in enumerate(models): if m.id == self.id: models[i] = self # 保存 # __dict__ 是包含了对象所有属性和值的字典 data = [m.__dict__ for m in models] path = self.db_path() save(data, path)
def load(path): """ 本函数从一个文件中载入数据并转化为 dict 或者 list path 是保存文件的路径 """ log('load 当前工作目录和数据相对路径 {} {}'.format(os.getcwd(), path)) # 文件不存在就写入默认空数组文件 if not os.path.exists(path): log('load 路径不存在,写入默认空数组数据。') # db 文件夹不存在,save 会报错 # xx.txt 不存在,会自动创建 save([], path) with open(path, 'r', encoding='utf-8') as f: s = f.read() log('load 反序列化前和\n<{}>'.format(s)) data = json.loads(s) log('load 反序列化后\n<{}>'.format(data)) return data
def save(data, path): """ 本函数把一个 dict 或者 list 写入文件 data 是 dict 或者 list path 是保存文件的路径 """ # json 是一个序列化/反序列化(上课会讲这两个名词) list/dict 的库 # indent 是缩进 # ensure_ascii=False 用于保存中文 log('save 当前工作目录和数据相对路径 {} {}'.format(os.getcwd(), path)) log('save 序列化前\n<{}>'.format(data)) s = json.dumps(data, indent=2, ensure_ascii=False) log('save 序列化后\n<{}>'.format(s)) with open(path, 'w+', encoding='utf-8') as f: f.write(s)
def route_login_view(request): """ 登录页面视图 """ log('login, headers', request.headers) log('login, cookies', request.cookies) user = current_user(request) log('current user', user) result = request.query.get('result', '') result = urllib.parse.unquote_plus(result) return html_response( 'login.html', result=result, username=user.username )
def route_login(request): """ 登录页面的路由函数 """ log('login, headers', request.headers) log('login, cookies', request.cookies) user_current = current_user(request) log('current user', user_current) form = request.form() user_login, result = User.login_user(form) result = urllib.parse.quote_plus(result) if user_login is not None: session_id = Session.add(user_login.id) headers = {'Set-Cookie': 'session_id={}'.format(session_id)} else: headers = {} # return redirect('/todo') return redirect('/login/view', result=result, headers=headers)
def one(cls, **kwargs): sql_where = ' AND '.join(['`{}`=%s'.format(k) for k in kwargs.keys()]) sql_select = 'SELECT * FROM {} WHERE {}'.format( cls.table_name(), sql_where) log('ORM one <{}>'.format(sql_select)) values = tuple(kwargs.values()) connection = cls._pymysql_connection() try: with connection.cursor() as cursor: log('ORM execute <{}>'.format( cursor.mogrify(sql_select, values))) cursor.execute(sql_select, values) result = cursor.fetchone() finally: log('finally 一定会被执行,就算 在 return 之后') connection.close() if result is None: return None else: m = cls(result) return m
def add(cls, form, user_id, weibo_id): form['user_id'] = user_id form['weibo_id'] = weibo_id c = Comment.new(form) log('comment add', c, user_id, weibo_id, form) return c
def expired(self): now = time.time() result = self.expired_time < now log('expired', result, self.expired_time, now) return result