zoukankan      html  css  js  c++  java
  • web框架

    1. 今日目标

    2.【了解】WEB框架概念

    • 静态资源:可以提前准备的,不经常改变的资源。(png,jpg,css,js等)

    • 动态资源:不能提前准备的,经常改变的资源。(html)

    • Web框架:为web服务器提供动态请求服务的程序

    • WSGI协议(了解): web服务器和web框架通信规则.

    3.【应用】miniWeb框架开发

    • 框架职责:

      接收web服务器的动态资源请求,给web服务器提供处理动态资源请求的服务。

    • 判断动态资源

      • 根据请求资源路径的后缀名进行判断

        • 如果请求资源路径的后缀名是.html则是动态资源请求, 让web框架程序进行处理。

        • 否则是静态资源请求,让web服务器程序进行处理。

    • 处理客户端的动态资源请求

      1. 创建web框架程序

      2. 接收web服务器的动态资源请求

      3. 处理web服务器的动态资源请求并把处理结果返回给web服务器

      4. web服务器把处理结果组装成响应报文发送给浏览器

    • 核心代码:

    • Web.py

              # 1.根据请求资源路径的后缀判断是否动态资源(.html的资源是动态资源)
             if request_path.endswith(".html"):
                 """动态资源请求"""
                 # 1.1 准备请求资源信息
                 request_info = {
                     "request_path": request_path
                     # ....
                }

                 #   2.如果是动态请求,把动态请求交给web框架处理。
                 #   3.WEB框架处理动态请求,把处理结果返回给web服务器
                 data = framework.handler_request(request_info)
                 status, headers, body = data

                 #   4.web服务器把处理结果拼接成响应报文返回给web浏览器
                 #   响应行
                 #       协议版本 状态码 状态描述
                 #   响应头
                 #   空行
                 #   响应体

                 #   响应行
                 #       协议版本 状态码 状态描述

                 response_line = "HTTP/1.1 %s " % status

                 response_head = ""
                 for header in headers:
                     # response_head += f"{header[0]}: {header[1]}"
                     response_head += "%s: %s " % header

                 response_body = body

                 response_data = (response_line + response_head + " " + response_body).encode("utf-8")

                 new_socket.send(response_data)

             else:
                 """静态资源请求"""
      • framework.py



      import time


      # 返回/index.html的响应数据
      def index():
         # 响应状态信息
         status = "200 OK"
         # 响应头信息
         headers = [("Server", "NBW/2.0")]
         # 响应体信息 = 模板 + 数据库数据
         body = time.ctime()

         return status, headers, body


      # 返回404页面的响应数据
      def not_found():
         # 响应状态信息
         status = "404 Not Found"
         # 响应头信息
         headers = [("Server", "NBW/2.0")]
         # 响应体信息 = 模板 + 数据库数据
         body = "Not Found"

         return status, headers, body



      def handler_request(request_info):
         # 2.接收web服务器的动态资源请求
         request_path = request_info['request_path']
         print("web服务器发送的动态请求路径: ", request_path)

         # 3.处理web服务器的动态资源请求并把处理结果返回给web服务器
         if request_path == "/index.html":
             data = index()
             return data

         else:
             data = not_found()
             return data

    4.【应用】模板替换

    • 思路

      • 拷贝资源(templates)到工程下

      • 在函数中读取对应的模板文件

        with open("template/index.html", "r") as file:
        file_data = file.read()
      • 使用正则替换网页中的内容 {%content%}

        body = file_data.replace("{%content%}", time.ctime())
      • 返回替换后的内容

        return status, headers, body

    5.【应用】路由列表功能开发(django)

    • 路由是请求的URL到处理函数的映射

    • 路由列表是用来保存每一个设置好的路由

      • 在路由列表中添加路由

        route_list = [
        ("/index.html", index),
        ("/center.html", center)
        ]
    • 用户的动态资源请求通过遍历路由列表找到对应的处理函数来完成。

      • 根据用户请求遍历路由列表处理用户请求

        for path, func in route_list:
        if request_path == path:
        data = func()
        return data

        else:
        data = not_found()
        return data

    6.【应用】路由装饰器(flask)

    • 使用带有参数的装饰器对处理函数进行装饰,并完成路由的添加功能。

      • 定义路由列表

        route_list = []
      • 定义带有参数的装饰器

        def route(path):

        def decorator(func):
        route_list.append((path, func))
           
            def inner():
                return func()
            return inner

        return decorator
      • 装饰处理函数

        @route("/index.html")
        def index():
        ...

        @route("/center.html")
        def center():
        ...

    7.【应用】显示股票信息页面的开发

    • 创建并导入数据到数据库

      • 创建数据库  create database stock_db charset=utf8

      • 使用数据库 use stock_db

      • 导入数据库(先客户端登录)

        • 准备脚本文件

        • 导入脚本   source stock_db.sql

    • 修改index函数

      • 连接数据库,获取数据

        • 导入模块

        • 建立连接

        • 创建游标

        • 使用游标执行sql

        • 获取查询的结果

          info_list = cs.fetchall()   # ((),(),(),...)
        • 关闭资源

          先关闭游标,在关闭连接

      • 替换为查询的数据

        • 思路:

          • 把查询的数据进行遍历,并且拼接html格式的文本

             body = ""
            # info : 就是元组类型, 直接实现字符串拼接
            for info in info_list:
                body += """<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>""" % info
          • 替换为拼接后的字符串

             # 3.3.替换模板中的变量为数据
            # replace: 字符串替换函数
            body = file_data.replace("{%content%}", body)
          • 注意:

            %s %s %s   ---> row        # row 是一个元组

      • 核心代码

        # 返回/index.html的响应数据
        @route("/index.html") # 1.route("/index.html") 2.@decorator -> index=decorator(index)
        def index():    # 0x11
        # 响应状态信息
        status = "200 OK"
        # 响应头信息
        headers = [("Server", "NBW/2.0")]
        # 响应体信息 = 模板 + 数据库数据
        body = time.ctime()

        # 2.1.打开模板文件
        with open("template/index.html", "r") as file:
            file_data = file.read()

        # 3.1.1.根据sql语句查询股票信息
        # 1)创建链接对象
        # 2)获取游标
        # 3)执行sql语句
        #   3.1) 提交
        # 4)获取查询的结果
        # 5)关闭游标
        # 6)关闭链接
        conn = pymysql.connect(host='127.0.0.1', port=3306,
                               user="root", password="mysql",
                               database="stock_db", charset="utf8")
        cs = conn.cursor()
        sql = "select * from info;"
        count = cs.execute(sql)
        print("查询到%d行数据" % count)
        info_list = cs.fetchall()
        # ((1, '000007', '全新好', '10.01%', '4.40%', Decimal('16.05'), Decimal('14.60'), datetime.date(2017, 7, 18)), ...)
        print(info_list)      # ((一行数据),(),(),(),...)
        cs.close()
        conn.close()

        # 3.2.替换模板中的变量为数据
        # 3.2.1 使用查询数据转换成前端需要的html代码

        body = ""
        # info : 就是元组类型, 直接实现字符串拼接
        for info in info_list:
            body += """<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>""" % info

        # 3.3.替换模板中的变量为数据
        # replace: 字符串替换函数
        body = file_data.replace("{%content%}", body)

        return status, headers, body

    8.【应用】个人中心数据接口的开发

    • 接口开发目的:前后端分离

    • 根据sql语句查询个人中心数据

      • 拼接两张表,显示个人中心数据

         sql = "select i.code,i.short,i.chg,i.turnover,i.price,i.highs,f.note_info from info i inner join focus f on i.id=f.info_id;"
    • 将个人中心数据转成json字符串并返回

      • 创建个人中心列表

        center_data_list = []
      • 遍历每行数据转换成字典

      • 添加字典到列表中

        for row in center_list:
        center_dict = {}
        center_dict['code'] = row[0]
        center_dict['short'] = row[1]
        center_dict['chg'] = row[2]
        center_dict['turnover'] = row[3]
        center_dict['price'] = str(row[4])
        center_dict['highs'] = str(row[5])
        center_dict['note_info'] = row[6]
        center_data_list.append(center_dict)
      • 把列表字典转成json字符串, 并在控制台显示

        json_str = json.dumps(center_data_list, ensure_ascii=False)
        print( type(json_str), json_str)
    • 浏览器通过指定接口地址获取web框架提供的数据。

      • 127.0.0.1:9090/center_data.html

    9.【应用】ajax请求数据渲染个人中心页面

    • 根据用户请求返回个人中心空模板文件数据

      • 打开模板文件,读取数据

        # 2.1.打开模板文件
        with open("template/center.html", "r") as file:
        file_data = file.read()
      • 替换模板文件中的%{content}%

      body = ""
      # 2.2.替换模板中的变量为数据
      # replace: 字符串替换函数
      body = file_data.replace("{%content%}", body)
    • 在个人中心模板文件添加ajax请求获取个人中心数据

      • 发送ajax请求获取个人中心页面数据: $.get()

        $.get("center_data.html", function (response) {
        console.log(response);
        },"JSON").error(function () {
        alert("链接失败,请重新链接.")
        });
    • 将个人中心数据在页面完成展示

      • 获取table标签元素对象

        var $table = $(".table");
      • 遍历数据列表获取每一个对象

      • 拼接html格式的文本

      • 拼接的html数据加入table标签中

        for(var i = 0; i < response.length; i++){
        // 获取数组对象
        var oBj = response[i];
        // 拼接成html展示的效果.
        var sTr = '<tr> ' +
            '           <td>'+oBj.code+'</td> ' +
            '           <td>'+oBj.short+'</td> ' +
            '           <td>'+oBj.chg+'</td> ' +
            '           <td>'+oBj.turnover+'</td> ' +
            '           <td>'+oBj.price+'</td> ' +
            '           <td>'+oBj.highs+'</td> ' +
            '           <td>'+oBj.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(sTr);
        }

    10.【了解】logging日志

    • 介绍:记录程序运行状态信息

    • 作用:

      • 记录程序运行状态信息

      • 收集用户的行为和喜好

      • 调bug

    • 级别:

      1. DEBUG

      2. INFO

      3. WARNING

      4. ERROR

      5. CRITICAL

    • 使用:

      • 导入模块

        import logging
      • 输入到控制台

        logging.debug("这是一个debug级别信息")
        logging.info("这是一个info级别信息")
        logging.warning("这是一个warning级别信息")
        logging.error("这是一个error级别信息")
        logging.critical("这是一个cirtical级别信息")
      • 设置输出级别和格式

        logging.basicConfig(level=logging.DEBUG,
                        format="%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s'",
                        filename="log.txt",
                        filemode="w")
    • logging日志在mini-web项目中应用:

      • INFO级别:静态请求或者动态请求

      • WARNING级别:参数传递错误

      • ERROR级别:404 异常

    11. 总结

  • 相关阅读:
    0317复利计算的回顾与总结
    0518 Scrum 项目 5.0
    0517 Scrum 项目4.0
    0512 Scrum 项目3.0
    实验三 进程调度模拟程序
    0505 Scrum 项目1.0
    0502团队项目 SCRUM团队成立
    0428 团队项目2.0
    0422团队项目
    实验二 作业调度模拟程序
  • 原文地址:https://www.cnblogs.com/zhangwei112/p/13586898.html
Copyright © 2011-2022 走看看