mini框架的简单版分享

1.  了解服务器与浏览器之间的简单传输

    (1)服务器接收到数据会发送给我们的框架

    (2)框架处理完数据会返回给服务器,服务器会把数据发送给浏览器

    (3)框架中包含很重要的函数,当框架写好后,只需要关心函数的执行

    (4)框架只需要让我们关心页面显示什么


2.  运行写好的服务器

import socket
import re
import multiprocessing
import mini_web

class WebServer(object):
    """这个服务器类"""

    def __init__(self):
        """初始化tcp服务器"""
        # 1. 创建套接字
        self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        # 2. 绑定
        self.tcp_server_socket.bind(("", 8899))

        # 3. 变为监听套接字
        self.tcp_server_socket.listen(128)

    def service_client(self, new_socket):
        """为这个客户端返回数据"""

        # 1. 接收浏览器发送过来的请求 ,即http请求
        # GET / HTTP/1.1
        # .....
        request = new_socket.recv(1024).decode("utf-8")
        request_lines = request.splitlines()
        print("")
        print(">" * 20)
        print(request_lines)

        # GET /index.html HTTP/1.1
        # get post put del
        file_name = ""
        ret = re.match(r"[^/]+(/[^ ]*)", request_lines[0])
        if ret:
            file_name = ret.group(1)
            # print("*"*50, file_name)
            if file_name == "/":
                file_name = "/index.html"

        # 如果是html那么会调用mini_web上的application返回页面数据
        if file_name.endswith(".html"):  # 伪静态,动态改装成静态代码,一般就是后缀改成.html

            url_params = dict()  # 给mini_web传参数的
            url_params['file_name'] = file_name

            body = mini_web.application(url_params, self.head_params)  # 调用框架处理

            head = "HTTP/1.1 %s\r\n" % self.stauts

            # 拼接我们的响应头
            for temp in self.params:
                head += "%s:%s\r\n" % temp

            content = head + "\r\n" + body

            new_socket.send(content.encode("utf-8"))

        else:
            # 返回静态的数据
            # 2. 返回http格式的数据,给浏览器
            try:
                f = open("./static" + file_name, "rb")
            except:
                response = "HTTP/1.1 404 NOT FOUND\r\n"
                response += "\r\n"
                response += "------file not found-----"
                new_socket.send(response.encode("utf-8"))
                print("文件找不到!")

            else:
                html_content = f.read()
                f.close()
                # 2.1 准备发送给浏览器的数据---header
                response = "HTTP/1.1 200 OK\r\n"
                response += "\r\n"
                # 2.2 准备发送给浏览器的数据---boy
                # response += "hahahhah"

                # 将response header发送给浏览器
                new_socket.send(response.encode("utf-8"))
                # 将response body发送给浏览器
                new_socket.send(html_content)

        # 关闭套接
        new_socket.close()

    def run_server(self):
        """用来完成整体的控制"""

        while True:
            # 4. 等待新客户端的链接
            new_socket, client_addr = self.tcp_server_socket.accept()

            # 5. 为这个客户端服务
            p = multiprocessing.Process(target=self.service_client, args=(new_socket,))
            p.start()

            new_socket.close()

        # 关闭监听套接字
        tcp_server_socket.close()

    def head_params(self, stauts, params):
        """ 把响应头存起来进行后期的拼接"""
        self.stauts = stauts
        self.params = params

def main():
    server = WebServer()
    server.run_server()


if __name__ == "__main__":

    main()

3.  在写好的框架里直接执行函数部分

    (1)框架部分

import re
from urllib.request import unquote  # 解码

# 定义空字典,用来存储路径跟对应的函数引用
from pymysql import connect

# 这个是路径跟方法的函数
url_dict = dict()

# start_response用来框架给服务器传响应头的数据
# environ用来得到服务器传过来的文件路径
def application(environ, start_response):
    """返回具体展示的界面给服务器"""
    start_response('200 OK', [('Content-Type', 'text/html;charset=utf-8')])  # 返回响应头

    # 根据不同的地址进行判断
    file_name = environ['file_name']

    for key, value in url_dict.items():
        match = re.match(key, file_name)  # 你的地址跟你的规则一致
        if match:
            # 匹配了
            return value(match)  # 调用匹配到的函数引用,返回匹配的页面内容

    else:
        # 说明没找到

        return "not page is find!"

# 这个装饰器传参,用来完成路由的功能
def route(url_address):  # url_address表示页面的路径
    """主要的目的自动添加路径跟匹配的函数到我们的url字典中"""

    def set_fun(func):
        def call_fun(*args, **kwargs):
            return func(*args, **kwargs)

        # 根据不同的函数名称去添加到字典中
        url_dict[url_address] = call_fun

        return call_fun

    return set_fun

    (2)函数的执行: 显示一个简单的从前端获取的网页界面,可以实现数据的增删改查

@route("/index.html")
def index(match):
    """ 显示股票界面 """
    """
    1. 打开前端给的网页界面
    2. 连接数据库导入数据
    3. 拼接数据到表格中

    4. 返回数据

    """
    # 打开前端给的网页
    with open("./templates/index.html") as f:
        content = f.read()

    # 得到一行数据
    row_str = """<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="%s">
        </td>
        </tr>"""

    # 从获取数据库得到数据
    # 链接数据库
    conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')

    # 得到游标
    cs1 = conn.cursor()

    # 执行sql语句
    sql = '''select * from info;'''
    print(sql)
    cs1.execute(sql)

    # 得到数据
    data = cs1.fetchall()

    # 打印所有数据
    for temp in data:
        print(temp)

    # 关闭
    cs1.close()
    conn.close()

    # 定义表格的数据  
    table_str = ""
    for temp in data:
        table_str += row_str % (temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], temp[7], temp[1])

    # 使用正则替换我们的数据
    content_new = re.sub(r'\{%content%\}', table_str, content)

    return content_new

@route("/center.html")
def center(match):
    """ 显示个人界面 """
    # 打开前端给的网页
    with open("./templates/center.html") as f:
        content = f.read()

    # 要替换的一行数据
    row_str = """ <tr>
             <td>%s</td>
             <td>%s</td>
             <td>%s</td>
             <td>%s</td>
             <td>%s</td>
             <td>%s</td>
             <td>%s</td>
             <td>
                 <a type="button" class="btn btn-default btn-xs" href="/update/%s.html"> <span class="glyphicon glyphicon-star" aria-hidden="true"></span> 修改 </a>
             </td>
             <td>
                 <input type="button" value="删除" id="toDel" name="toDel" systemidvaule="%s">
             </td>
        </tr>"""
    # 链接数据库得到数据
    # 链接数据库
    conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')

    # 得到游标
    cs1 = conn.cursor()

    # 执行sql语句
    sql = ''' select info.code,info.short,info.chg,info.turnover,info.price,info.highs,focus.note_info from focus inner join info on focus.info_id = info.id; '''
    print(sql)
    cs1.execute(sql)

    # 得到数据
    data = cs1.fetchall()

    # 打印所有数据
    for temp in data:
        print(temp)

    # 关闭
    cs1.close()
    conn.close()

    # 定义表格中的数据
    table_str = ""
    for temp in data:
        table_str += row_str % (temp[0], temp[1], temp[2], temp[3], temp[4], temp[5], temp[6], temp[0], temp[0])

    # 拼接数据
    content_new = re.sub(r"\{%content%\}", table_str, content)

    #  返回数据
    return content_new

# 接下来执行数据的增删改查

"""添加"""

@route("/add/(\d+).html")
def add(match):
    """对数据进行判断:存在无法添加,不存在就添加"""
    # 得到code 进行操作
    code = match.group(1)

    # 链接数据库进行操作
    conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')

    # 得到游标
    cs1 = conn.cursor()

    # 执行sql语句
    sql = ''' select * from focus where info_id in (select id from info where code = %s); '''
    cs1.execute(sql, (code,))

    # 判断是否有数据
    if cs1.fetchone():
        """已经有数据"""
        cs1.close()
        conn.close()

        return "亲?已经有数据了"
    else:
        """没有数据"""
        sql = """ insert into focus(info_id) (select id from info where code = %s); """
        cs1.execute(sql, (code,))

        # 修改完提交数据
        conn.commit()

        # 关闭
        conn.close()
        cs1.close()

        # 返回数据
        return "亲?添加成功"

"""删除"""

@route("/del/(\d+).html")
def delete_data(match):
    """根据code去删除数据"""
    # 得到code
    code = match.group(1)

    # 链接数据库得到数据
    conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')

    # 得到游标
    cs1 = conn.cursor()

    # 执行sql语句
    sql = '''delete from focus where info_id in (select id from info where code = %s);'''
    print(sql)
    cs1.execute(sql, (code,))

    # 得到数据
    data = cs1.fetchall()

    # 打印所有数据
    for temp in data:

        print(temp)

    # 提交数据
    conn.commit()

    # 关闭
    cs1.close()
    conn.close()

    # 返回数据
    return "亲,删除成功"

"""更新"""

@route("/update/(\d+).html")
def update(match):
    """显示一个新的界面"""
    # 得到code
    code = match.group(1)

    # 从前端给的网页里打开内容
    with open("./templates/update.html")as f:
        content = f.read()

    # 替换我们的code
    content = re.sub(r"\{%code%\}", code, content)

    # 链接数据库得到数据
    conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')

    # 得到游标
    cs1 = conn.cursor()

    # 执行sql语句
    sql = '''select note_info from focus where info_id in(select id from info where code = %s);;'''
    print(sql)
    cs1.execute(sql, (code,))

    # 得到数据
    data = cs1.fetchall()

    # 打印所有数据
    for temp in data:
        print(temp)

    # 关闭
    cs1.close()
    conn.close()

    # 得到数据
    print(data[0][0])

    # 将数据替换
    content = re.sub(r"\{%note_info%\}", data[0][0], content)

    # 返回数据
    return content

"""接下来更新数据"""

@route("/update/(\d+)/(.*).html")
def update_data(match):
    # 获取code
    code = match.group(1)

    # 获取内容
    note_info = match.group(2)

    # 链接数据库获取数据
    conn = connect(host='localhost', port=3306, user='root', password='mysql', database='stock_db', charset='utf8')

    # 得到游标
    cs1 = conn.cursor()

    # 执行sql语句
    sql = '''update focus set note_info = %s where info_id in (select id from info where code = %s);'''
    print(sql)
    cs1.execute(sql, (note_info, code))

    # 得到数据
    data = cs1.fetchall()

    # 打印所有数据
    for temp in data:
        print(temp)

    # 提交数据
    conn.commit()

    # 关闭
    cs1.close()
    conn.close()

    # 返回数据

    return " 更新成功 "

    (4)在浏览器输入ip地址和端口号进行访问即可


猜你喜欢

转载自blog.csdn.net/wpb74521wrf/article/details/80578842