Esempio n. 1
0
    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")
Esempio n. 2
0
    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")
Esempio n. 3
0
 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")
Esempio n. 4
0
    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
Esempio n. 5
0
    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)
Esempio n. 6
0
    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")
Esempio n. 7
0
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
Esempio n. 8
0
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