async def execute(self, req: Request, res): if req.method == "GET": await res.render("user/login.html", title="登录") elif req.method == 'POST': login_param = req.get_var_as_str(b"login") password = req.get_var_as_str(b"password") db = self.db user_record = (await db((db.auth_user.user_name == login_param) | (db.auth_user.user_email == login_param) | (db.auth_user.user_phone == login_param) ).select()).first() _next = None if user_record: transcode = db.auth_user.user_password.requires(password)[0] if transcode == user_record.user_password: # 将登录用户写入 session await req.set_session("current_user", user_record.as_dict()) await res.redirect("/user/profile") else: alert_msg = "用户名或密码错误" await res.render("user/login.html", title="登录", alert_msg=alert_msg) else: await res.end(b"Unsupported method")
async def execute(self, req: Request, res): db = self.db alert_msg = "" if req.method == 'GET': await res.render("user/register.html", title="注册", alert_msg=alert_msg) elif req.method == "POST": login_name = req.get_var_as_str(b"login_name") email = req.get_var_as_str(b"email") phone = req.get_var_as_str(b"phone") password = req.get_var_as_str(b"password") # 将密码进行加密存储 password = self.db.auth_user.user_password.requires(password)[0] try: if (await self.db.auth_user.insert( user_name=login_name, user_email=email, user_phone=phone, user_password=password, reg_time=datetime.datetime.utcnow())): user_record = (await db(db.auth_user.user_name == login_name ).select()).first() await req.set_session("current_user", user_record.as_dict()) await res.redirect("/user/profile") except IntegrityError as err: alert_msg = "注册失败" # 错误提示信息如: # Duplicate entry '[email protected]' for key 'user_email' # 该正则的目的是将字段名从错误提示信息中提取出来 result = re.search("Duplicate entry .* for key '(\\w+)'", err.args[1]) error_msg = result[1] if error_msg == 'user_email': alert_msg = "邮箱已被占用" elif error_msg == 'user_name': alert_msg = "用户名已被占用" elif error_msg == 'user_phone': alert_msg = "手机号已被占用" await res.render("user/register.html", title="注册", alert_msg=alert_msg) else: alert_msg = "注册失败" await res.render("user/register.html", title="注册", alert_msg=alert_msg) else: await res.end(b"Method not supported")
async def execute(self, req: Request, res): if req.method == "GET": await res.render("user/pub_house.html", title="发布房源") elif req.method == 'POST': user = await req.get_session("current_user") title = req.get_var_as_str(b"house_res_title") content = req.get_var_as_str(b'house_res_content') await self.db.house_res.insert(res_title=title, res_content=content, pub_time=datetime.datetime.now(), owner_id=user['id']) await res.redirect(f"/house/by_id/{self.db.lastrowid}") pass else: await res.end(b"Method not supported")
async def execute(self, req: Request, res): keyword = req.get_var_as_str(b"k") async def row_render(db, req, res, row, fields): return await res.render_string("house/all_row.html", row=row) db = self.db grid = await data_grid.grid( db, req, res, # 根据指定的关键字查询数据库 ((db.house_res.res_title.like(f"%{keyword}%")) | (db.house_res.res_content.like(f"%{keyword}%"))) & (db.house_res.owner_id == db.auth_user.id), fields=[ # 只显示指定的字段 db.house_res.id, db.house_res.res_title, db.house_res.pub_time, db.auth_user.user_name, db.auth_user.user_phone, ], order_by=~db.house_res.id, row_render=row_render, header_render=lambda *args: "") await res.render("house/all.html", title=f"搜索结果 - {keyword}", grid=grid) pass
async def execute(self, req: Request, res): house_id = req.arg(0) house = await self.db.house_res.by_id(house_id) owner = None comments_grid = "" async def row_render(db, req, res, row, fields): return await res.render_string("house/comment_row.html", row=row) if house: owner = await self.db.auth_user.by_id(house['owner_id']) if req.method == 'POST': # 如果是POST请求,则尝试读取评论数据 comment = req.get_var_as_str(b"comment") if comment: await self.db.house_res_comment.insert( user_id=owner['id'], house_res_id=house['id'], comment_content=comment, comment_time=datetime.datetime.now()) db = self.db comments_grid = await data_grid.grid( db, req, res, (db.house_res_comment.house_res_id == house['id']) & (db.house_res_comment.user_id == db.auth_user.id), fields=[ # 只显示指定的字段 db.house_res_comment.id, db.house_res_comment.comment_content, db.house_res_comment.comment_time, db.auth_user.user_name ], order_by=~db.house_res_comment.id, row_render=row_render, header_render=lambda *args: "") await res.render("house/by_id.html", title=house['res_title'] if house else '找不到房源', house=house, owner=owner, comments_grid=comments_grid)
async def execute(self, req: Request, res): db = self.db group_id = req.get_var_as_str(b"group_id") group_role = req.get_var_as_str(b"role") group_description = req.get_var_as_str(b"description") if not await auth.has_membership(db, req, res, 'admin'): await res.end(b"AccessDenied") return if not group_id: # 如果没有指定 id,则创建新组 await db.auth_group.insert(role=group_role, description=group_description) else: # 如果已指定 id,则更新指定的组 await db(db.auth_group.id == group_id ).update(description=group_description) await res.end(b"ok")
def default_foot_render(db, request: Request, response, current_page_index, paginate, all_count): """ 默认的底部选择器链接渲染器,算法为根据当前页码向左最多呈现5个页码 链接,向右最多呈现5个页码链接 :param db: :param request: :param response: :param current_page_index: :param paginate: :param all_count: :return: """ vars = {} for k in request.query_vars: vars[k.decode(config.GLOBAL_CHARSET)] = unquote( request.get_query_var(k).decode(config.GLOBAL_CHARSET)) def create_link(page_index, label=None, active=False): vars['page_index'] = page_index return f"<li class=\"page-item {'active' if active else ''}\">" \ f" <a " \ f" class=\"btn-page-number page-link\" " \ f" href='{request.path}?{url.dict_to_url_params(vars)}'>" \ f" {(page_index + 1) if not label else label}" \ f" </a>" \ f"</li>" last_page_index = math.ceil(all_count / paginate) - 1 html_str = "" if last_page_index > 0: page_number_btns = [create_link(current_page_index, active=True)] i = 0 for i in range(current_page_index - 1, current_page_index - 5, -1): if i < 0: break page_number_btns.insert(0, create_link(i)) if i > 0: page_number_btns.insert(0, create_link(0, "<<")) for i in range(current_page_index + 1, current_page_index + 5): if i > last_page_index: break page_number_btns.append(create_link(i)) if i < last_page_index: page_number_btns.append(create_link(last_page_index, ">>")) # dump html content html_str += " ".join(page_number_btns) return html_str
async def grid(db, request: Request, response: Response, query, fields=None, order_by=None, paginate=20, row_render=default_row_render, header_render=default_header_render, foot_render=default_foot_render): """ 生成分页的表格,原理是获取页面中的页码参数,以查询数据库, 并根据页码生成对应底部选择器 :param db: :param request: :param response: :param query: 该表格对应的查询语句 :param fields: 要呈现的字段,默认为全部字段 :param order_by: 排序方式 :param paginate: 每页数据条数 :param row_render: 行渲染器,用于自定义行内容 :param header_render: 表头渲染器,用于自定义表头 :param foot_render: 底部选择器渲染器,用于自定义选择器 :return: """ page_index = int(request.get_query_var(b"page_index", b"0")) # 获取符合条件的所有数据的条数,用于计算分页 all_count = await db(query).count() # 如果外部指定了字段,则呈现指定的字段数据 if fields: db_rows = await db(query).select(*fields, limitby=(paginate * page_index, (page_index + 1) * paginate), orderby=order_by) # 如果外部没有指定字段,则呈现所有字段数据 else: db_rows = await db(query).select(limitby=(paginate * page_index, (page_index + 1) * paginate), orderby=order_by) table_body_rows_html_content = "" # 渲染表中的行 for r in db_rows: row_render_result = row_render(db, request, response, r, db_rows.field_names) if isinstance(row_render_result, Awaitable): row_render_result = await row_render_result if isinstance(row_render_result, str): row_content = row_render_result elif isinstance(row_render_result, bytes): row_content = row_render_result.decode("utf-8") else: row_content = '' table_body_rows_html_content += row_content rendered_header_content = '' rendered_header_result = header_render(db, request, response, db_rows.field_names) if inspect.isawaitable(rendered_header_result): rendered_header_content = await rendered_header_result else: rendered_header_content = rendered_header_result if isinstance(rendered_header_content, str): table_header_html_content = rendered_header_content elif isinstance(rendered_header_content, bytes): table_header_html_content = rendered_header_content.decode("utf-8") else: table_header_html_content = "" table_html_content = \ f"<div>" \ f" <div>" \ f" <table class='data-grid table'>" \ f" <thead>{table_header_html_content}</thead>" \ f" <tbody>{table_body_rows_html_content}</tbody>" \ f" </table>" \ f" </div>" \ f" <div class='page-numbers-container'>" \ f" <nav>" \ f" <ul class='pagination'>" \ f" {foot_render(db, request, response, page_index, paginate, all_count)}" \ f" </ul>" \ f" </nav>" \ f" </div>" \ f"</div>" return table_html_content