〖Python〗-- Web框架本质

【web框架前戏】

自己开发Web框架
  - socket
  - http协议
  - HTML知识
  - 数据库(pymysql,SQLAlchemy)

小总结

 

应用:通过函数去调用对应的页面,先获取响应的页面信息,再传给客户端!(看代码!)

1、静态页面:网址内容写死,直接跳转显示,数据无法动态更新。

import socket
import pymysql

def foo(request):
    f = open("login.html","rb")
    data = f.read()
    f.close()
    return data

def var(request):
    f = open("userinfo.html","rb")
    data = f.read()
    f.close()
    return data



routers=[
    ("/xxx",foo),
    ("/ooo",var),
]

#web服务
def run():
    sk = socket.socket()
    sk.bind(("127.0.0.1",8080))
    sk.listen(5)

    while True:
        conn,addr = sk.accept()
        data = conn.recv(8096)   #接收浏览器发送的请求头
        data_str = str(data,encoding="utf-8")
        headers,bodys = data_str.split("

")
        temp_list = headers.split("
")
        method,url,protocal = temp_list[0].split(" ")

        conn.send(b"HTTP/1.1 200 OK

") #回应响应头
        func_name = None
        for item in routers:
            if item[0] == url:
                func_name = item[1]
                break

        if func_name:
            res = func_name(data_str)
        else:
            res = b"404"

        conn.send(res) #回应响应体(网页主体文本内容)
        conn.close()

if __name__ == '__main__':
    run()
index.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="d1">
    <h3>!就是测试!</h3>
    <form action="">
        <input type="text" name="username"><br>
        <input type="password" name="pwd"><br>
        <input type="submit" name="submit" value="提交">
    </form>
</div>

</body>
</html>
login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <table border="1">
        <thead>
            <tr>
                <th>ID</th>
                <th>name</th>
                <th>email</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>1</td>
                <td>alex</td>
                <td>alex@163.com</td>
            </tr>
            <tr>
                <td>2</td>
                <td>root</td>
                <td>root@qq.com</td>
            </tr>
        </tbody>
    </table>
</body>
</html>
userinfo.html

2、动态页面:网站内容是从数据库中读取。数据库中的数据变动,对应的页面上的数据也会发生变动。(多看看代码,分析下数据和模版渲染的执行方式!)

#!/usr/bin/env python
# _*_ coding:utf-8 _*_

import socket
import pymysql
from jinja2 import Template

def foo(request):
    f = open("login.html","rb")
    data = f.read()
    f.close()
    return data

def var(request):
    f = open("userinfo.html","rb")
    data = f.read()
    f.close()
    return data

def f3(request):

    conn = pymysql.connect(
        host="127.0.0.1",
        port=3306,
        user="root",
        password="",
        database="day63",
        charset="utf8"
    )
    cursor = conn.cursor()
    sql = "select id,name,email from users"
    cursor.execute(sql)
    res = cursor.fetchall()
    cursor.close()
    conn.close()

    userinfo = []
    for item in res:
        tp = "<tr>" 
             "<td>%s</td>" 
             "<td>%s</td>" 
             "<td>%s</td>" 
             "</tr>"%(item[0],item[1],item[2])
        userinfo.append(tp)
    s = "".join(userinfo)

    f = open("userlist.html",mode="r",encoding="utf-8")
    data = f.read()
    f.close()

    #模版渲染(模版+数据)
    data = data.replace("@@sss@@",s)
    return bytes(data,encoding="utf-8")

def f4(request):

    conn = pymysql.connect(host='127.0.0.1', port=3306, user='root', passwd='', db='day63')
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    sql = "select id,name,email from users"
    cursor.execute(sql)
    user_list = cursor.fetchall()
    cursor.close()
    conn.close()

    f = open('hostlist.html', 'r', encoding='utf-8')
    data = f.read()
    f.close()

    #使用第三方工具实现模版渲染
    template = Template(data)
    data = template.render(xxxx=user_list,sus="nihao")
    return bytes(data,encoding="utf-8")

routers=[
    ("/xxx",foo),
    ("/ooo",var),
    ("/sss", f3),
    ("/yyy",f4),
]

def run():
    sk = socket.socket()
    sk.bind(("127.0.0.1",8080))
    sk.listen(5)

    while True:
        conn,addr = sk.accept()
        data = conn.recv(8096)
        data_str = str(data,encoding="utf-8")
        headers,bodys = data_str.split("

")
        temp_list = headers.split("
")
        method,url,protocal = temp_list[0].split(" ")
        conn.send(b"HTTP/1.1 200 OK

")

        func_name = None
        for item in routers:
            if item[0] == url:
                func_name = item[1]
                break

        if func_name:
            res = func_name(data_str)
        else:
            res = b"404"

        conn.send(res)
        conn.close()

if __name__ == '__main__':
    run()
index.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <table border="1">
        <thead>
            <tr>
                <td>ID</td>
                <td>用户名</td>
                <td>邮箱</td>
            </tr>
        </thead>
        <tbody>
            {% for row in xxxx %}
                <tr>
                    <td>{{row.id}}</td>
                    <td>{{row.name}}</td>
                    <td>{{row.email}}</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
{{sus}}
</body>
</html>
hostlist.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div class="d1">
    <h3>!就是测试!</h3>
    <form action="">
        <input type="text" name="username"><br>
        <input type="password" name="pwd"><br>
        <input type="submit" name="submit" value="提交">
    </form>
</div>

</body>
</html>
login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <table border="1">
        <thead>
            <tr>
                <th>ID</th>
                <th>name</th>
                <th>email</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>1</td>
                <td>alex</td>
                <td>alex@163.com</td>
            </tr>
            <tr>
                <td>2</td>
                <td>root</td>
                <td>root@qq.com</td>
            </tr>
        </tbody>
    </table>
</body>
</html>
userinfo.html
userlist.html

搞明白这些,虽然不敢保证说对web框架的本质有个深入的了解,但最起码可以知道他是怎么个工作流程!!!

原文地址:https://www.cnblogs.com/SHENGXIN/p/7636527.html