python基础进阶之mini-Web框架

一、mini-Web框架

1、区分静态和动态资源的请求(使用框架程序处理客户端的动态资源请求操作)
    web.py中:
        # 把请求.html文件和其他文件的请求进行分离
        if not file_name.endswith(".html"):
            # 静态请求处理
            try:
                with open("static" + file_name, "rb") as f:
                    response_body = f.read()
            except:
                response_line = "HTTP/1.1 400 NOT FOUND\r\n"
                with open("static/404.html", "rb") as f:
                    response_body = f.read()

        else:
            # 动态请求处理
            response_status, response_headers, response_body = appclication(file_name)

            response_line = "HTTP/1.1 %s\r\n" % response_status
            response_header = "Content-Type: text/html;charset=utf-8\r\n"
            for i in response_headers:
                response_header += i[0] + ":" + i[1] + "\r\n"

            response_body = response_body.encode("utf-8")

    framework.py中:
        def appclication(file_name):
            """按照要求返回对应的相应内容给服务器"""
            if file_name == "/index.html":

                return index()

            elif file_name == "/center.html":

                return center()

            else:
                return not_found()

2、首页的初步展示

    framework.py中
        def index():
            """处理/index.html的请求"""
            status="200 OK"

            response_header = [("Server", "python12/2.0")]

            with open("templates/index.html", "r") as f:
                response_body = f.read()

            return status, response_header, response_body

    web.py中:
        如果发现css样式在页面中不显示,则把响应头中的 Content-Type: text/html;charset=utf-8,去掉(或者换成text/css, 但是要考虑其他种类文件,比较繁琐)
    

3、首页数据展示,实现模板替换功能
    def index():
        """处理/index.html的请求"""
        status="200 OK"

        response_header = [("Server", "python12/2.0")]

        with open("templates/index.html", "r") as f:
            response_body = f.read()

        # 连接数据库,获取数据
        conn1 = pymysql.connect(host="localhost", port=3306, user="root", password="mysql", database="stock_db", charset="utf8")
        cs = conn1.cursor()

        sql = "select * from info;"
        cs.execute(sql)
        data = cs.fetchall()

        cs.close()
        conn1.close()

        # 准备模板
        html = ''
        for i in data:
            html+="""<tr><td>%s</td>
                        <td>%s</td>
                        <td>%s</td>
                        <td>%s</td>
                        <td>%s</td>
                        <td>%s</td>
                        <td>%s</td>
                        <td>%s</td>
                        <td><input type="button" value="添加" id="toAdd" name="toAdd" systemidvaule="000007"></td>
                </tr>""" % i

        # 替换模板
        response_body = response_body.replace("{%content%}", html)

        return status, response_header, response_body


4、路由字典的实现
    route_dict={
        "/index.html": index,
        "/center.html": center
    }


    def appclication(file_name):
        """按照要求返回对应的相应内容给服务器"""

        # 接下来项目中每添加一个页面或者有一个动态资源的请求,就会多一个if判断
        # 为了便于管理, 我们把请求路径和执行的函数之间的对应关系抽取出来,体现在一个路由字典中
        try:
            return route_dict[file_name]()
        except:
            return not_found()

5、装饰器方式的添加路由

    先解答以下两个题目
        题目1(带参数的装饰器):
            定义一个装饰器,对函数使用装饰器实现简单的动态验证, 对f1函数添加 验证1, 对f2函数添加 验证2

        题目2:
            先定义一个空列表lst,用装饰器实现以下功能:

            每次在这个python文件中定义任意一个函数的时候,列表都会自动添加一个元素,这个元素就是刚刚定义的这个函数的引用,
            即:通过  lst[0]() 可以调用刚才第一个函数,通过  lst[1]() 可以调用刚才第二个函数


    # 上面的方式如果项目中每添加一个页面或者有一个动态资源的请求,仍旧需要手动往route_dict字典中添加元素
    # 使用装饰器装饰对应的函数,可以让每一个对应关系在函数定义的时候自动生成
    # 接下来使用装饰器来自动生成这个路由字典

    route_dict = dict()


    def route(url):
        def route_(func):
            route_dict[url] = func
            def fn_in(*args, **kwargs):
                return func()
            return fn_in
        return route_

    @route("/index.html")
    def index():
        """处理/index.html的请求"""
        ...

    @route("/center.html")
    def center():
        """处理/center.html的请求"""
        ...

6、个人中心数据接口的开发(center)

    上面我们书写的index函数,是直接返回整个页面给前端,
    其实,框架程序还可以开发数据接口,为客户端程序提供数据服务,即,我们后端只把数据从数据库中查询出来,返回这些数据提供给前端,而前端可以做ajax请求来获取这些数据,在ajax的success回调函数中把这些数据填到中模板中

    前端center.html页面中:
        <script>
            $(document).ready(function(){
                
                $.ajax({
                    url:"/center_data.html",
                    type:"GET",
                    dataType:"JSON",
                    success:function(resp){
                        console.log(resp)
                    }
                })

            });
        </script>
    framework.py中添加一个接口函数center_data,在center_data函数中:

        @route("/center_data.html")
        def center_data():
            """返回/center_data.html的请求"""
            status = "200 OK"

            response_header = [("Server", "python12/2.0")]

            # 1、连接数据库, 查询和获取前端需要展示的数据
            conn1 = pymysql.connect(host="localhost", port=3306, user="root", password="mysql", database="stock_db",
                                    charset="utf8")
            cs = conn1.cursor()

            sql = "select i.code,i.short,i.chg,i.turnover,i.price,i.highs,f.note_info from info as i inner join focus as f on i.id=f.info_id;"
            cs.execute(sql)
            data = cs.fetchall()  # 是一个元组
            cs.close()
            conn1.close()

            # 2、把数据转成json格式的字符串,并返回这个json格式的字符串
            # 注意:元组的格式不是json格式,而data是一个元组,我们需要把它处理成字典,再转json字符串
            data_list = list()

            for i in data:
                data_list.append({
                    "code": i[0],
                    "short": i[1],
                    "chg": i[2],
                    "turnover": i[3],
                    "price": str(i[4]),
                    "highs": str(i[5]),
                    "note_info": i[6]
                })

            json_str = json.dumps(data_list,ensure_ascii=False)   # 把data_list转成json格式的字符串
            # ensure_ascii=False即不使用ascii编码,可以在前端完好地显示中文

            return status, response_header, json_str


    总结————个人中心数据接口的开发步骤:
        # 1、连接数据库, 查询和获取前端需要展示的数据
        # 2、把数据转成json格式的字符串,并返回这个json格式的字符串


7、前端获取到接口后,请求这个接口的数据,填入页面中


    在center.html的ajax的success回调函数中:

        for(var i=0;i<resp.length; i++){

            $tr = $('<tr><td>'+ resp[i].code +'</td><td>'+ resp[i].short +'</td><td>'+ resp[i].chg +'</td><td>'+ resp[i].turnover +'</td><td>'+ resp[i].price +'</td><td>'+ resp[i].highs +'</td><td>'+ resp[i].note_info +'</td><td><a type="button" class="btn btn-default btn-xs" href="/update/000007.html"> <span class="glyphicon glyphicon-star" aria-hidden="true"></span> 修改 </a></td><td><input type="button" value="删除" id="toDel" name="toDel" systemidvaule="000007"></td></tr>');

            $("table").append($tr);
        }

二、带有参数的装饰器
def fn(num):
def fn_(func):
def fn_in(*args, **kwargs):
print(“验证%s” % num)
func()
return fn_in
return fn_

@fn("A")   # 相当于 f1 = fn("A")(f1)
def f1():
    print("-----f1-----")


@fn("B")  # 相当于 f1 = fn("B")(f1)
def f2():
    print("-----f2-----")


f1()
f2()

结论:
    如果装饰器需要带参数,在原先书写的闭包装饰器外边再套一层函数,并在这个函数的最后返回次外层函数的引用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值