First, the web framework acquaintance

A handwritten simple web framework

1. 获取输入网址后缀

conn, addr = server.accept()
data = conn.recv(1024)

data = data.decode('utf-8')
current_path = data.split('\r\n')[0].split(' ')[1]
print(current_path)

conn.send(b'HTTP/1.1 200 ok\r\n\r\nhello world')
conn.close()


2. 根据不同后缀返回不同结果

conn, addr = server.accept()
data = conn.recv(1024)

data = data.decode('utf-8')
current_path = data.split('\r\n')[0].split(' ')[1]

conn.send(b'HTTP/1.1 200 OK\r\n\r\n')

if current_path == '/index':
    conn.send(b'index')

elif current_path == '/login':
    conn.send(b'login')

else:
    conn.send(b'hello world')

conn.close()
  1. Returns different HTML pages, depending on the suffix

    conn, addr = server.accept()
    data = conn.recv(1024)

    conn.send(b'HTTP/1.1 200 OK\r\n\r\n')

    data = data.decode('utf-8')
    current_path = data.split('\r\n')[0].split(' ')[1]

    if current_path == '/index':

     with open(r'a.html', 'rb') as f:
         conn.send(f.read())

    elif current_path == '/login':
    with open(r'b.html', 'rb') as f:
    conn.send(f.read())

    else:
    conn.send(b'hello world')
    conn.close()

Two, wsgiref achieve simple web framework

1. 往浏览器窗口返回固定值

from wsgiref.simple_server import make_server


def run(env, response):
    print(env)

    response('200 ok', [])

    return [b'hello world']

if __name__ == '__main__':
    server = make_server('127.0.0.1', 8080, run)
    server.serve_forever()


2. 获取输入后缀

from wsgiref.simple_server import make_server


def run(env, response):

    response('200 ok', [])

    current_path = env.get('PATH_INFO')

    print(current_path)

    return [b'hello world']

if __name__ == '__main__':
    server = make_server('127.0.0.1', 8080, run)
    server.serve_forever()


3. 根据不同后缀返回不同结果

from wsgiref.simple_server import make_server


def run(env, response):

    response('200 ok', [])

    current_path = env.get('PATH_INFO')

    if current_path == '/index':
        return [b'index']

    elif current_path == '/login':
        return [b'login']
    
    return [b'404 error']

if __name__ == '__main__':
    server = make_server('127.0.0.1', 8080, run)
    server.serve_forever()


4. 根据不同后缀调用不同函数处理

from wsgiref.simple_server import make_server


def index(env):
    return 'index'

def login(env):
    return 'login'

def errors(env):
    return '404'

urls = [
    ('/index', index),
    ('/login', login)
]

def run(env, response):

    response('200 ok', [])

    current_path = env.get('PATH_INFO')

    func = None

    for url in urls:

        if url[0] == current_path:
            func = url[1]
            break

    if func:
        res = func(env)

    else:
        res = errors(env)

    return [res.encode('utf_8')]

if __name__ == '__main__':
    server = make_server('127.0.0.1', 8080, run)
    server.serve_forever()


5. 将不同功能封装在不同模块中

    a. main
    
    from views import *
    from urls import urls
    from wsgiref.simple_server import make_server
    
    
    def run(env, response):
    
        response('200 ok', [])
    
        current_path = env.get('PATH_INFO')
    
        func = None
    
        for url in urls:
    
            if url[0] == current_path:
                func = url[1]
                break
    
        if func:
            res = func(env)
    
        else:
            res = errors(env)
    
        return [res.encode('utf_8')]
    
    if __name__ == '__main__':
        server = make_server('127.0.0.1', 8080, run)
        server.serve_forever()
    
    
    b. views(视图函数)
    
    def index(env):
        return 'index'
    
    def login(env):
        return 'login'
    
    def errors(env):
        return '404'
    
    
    c. urls(路由与视图函数的对应关系)
    
    from views import *
    
    
    urls = [
        ('/index', index),
        ('/login', login)
    ]

Third, make the page show the current time

1. 在urls中添加对应关系

urls = [
    ('/index', index),
    ('/login', login),
    ('/get_time', get_time),
]


2. 在templates中编写名为get_time的HTML模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
$$time$$
</body>
</html>


3. 在view中添加获取时间功能,将结果替换掉HTML页面中的字段。

def get_time(env):

    current_time = datetime.now().strftime('%Y-%m-%d %X')
    with open(r'templates/get_time.html', 'r', encoding='utf-8') as f:
        data = f.read()
    data = data.replace("$$time$$", current_time)
    return data

Fourth, make the page display dictionary

1. 在urls中添加对应关系

urls = [
    ('/index', index),
    ('/login', login),
    ('/get_time', get_time),
    ('/get_user', get_user),
]


2. 在templates中编写名为get_time的HTML模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<p>{{data}}</p>
<p>{{data['username']}}</p>
<p>{{data.password}}</p>
<p>{{data.get('hobby')}}</p>
</body>
</html>


3. 在views中导入jinja2模块,添加获取字典功能

from jinja2 import Template
def get_user(env):
    user_dict = {'username': 'byx', 'password': '123', 'hobby': ['read', 'game', 'running']}

    with open(r'templates/get_user.html', 'r', encoding='utf-8') as f:
        data = f.read()

    temp = Template(data)
    res = temp.render(data=user_dict)

    return res

Fifth, the dynamic display database

1. 在urls中添加对应关系

urls = [
    ('/index', index),
    ('/login', login),
    ('/get_time', get_time),
    ('/get_user', get_user),
    ('/get_db', get_db)
]


2. 在templates中编写名为get_db的HTML模板

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css">

</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <h2 class="text-center">用户数据展示</h2>
            <table class="table table-hover table-bordered table-striped">
                <thead>
                    <tr>
                        <th>id</th>
                        <th>username</th>
                        <th>password</th>
                    </tr>
                </thead>
                <tbody>
                    {%for user_dict in user_list%}
                        <tr>
                            <td>{{user_dict.id}}</td>
                            <td>{{user_dict.name}}</td>
                            <td>{{user_dict.password}</td>
                        </tr>
                    {%endfor%}
                </tbody>
            </table>
        </div>
    </div>
</div>
</body>
</html>


3. 在views中导入pymysql模块,连接数据库。通过jinja2模块导入get_db模板。

import pymysql
def get_db(env):

    conn = pymysql.connect(
        host = '127.0.0.1',
        port = 3306,
        user = 'root',
        password = '123',
        database = 'test',
        charset = 'utf8',
        autocommit = True
    )

    cursor = conn.cursor(pymysql.cursors.DictCursor)
    sql = 'select * from userinfo'
    affect_rows = cursor.execute(sql)
    data = cursor.fetchall()

    with open(r'templates/get_db.html', 'r', encoding='utf-8') as f:
        data1 = f.read()

    temp = Template(data1)
    res = temp.render(user_list=data)

    return res

VI Summary

1. 手写web框架

    1. 手动书写socket代码
    
    2. 手动处理HTTP数据
    
2. 基于wsgiref模块帮助我们处理socket以及HTTP数据

    wsgiref模块

        1. 请求来的时候,解析HTTP数据,打包成字典传输过来,便于操作各项数据。
        
        2. 响应走的时候,自动将数据打包成符合HTTP协议格式的样子,返回给前端。
        
3. 封装路由与视图函数的对应关系,以及视图函数文件

    1. urls.py

        路由与视图函数对应关系
    
    2. views.py
    
        视图函数(视图函数不单单指函数,也可以是类)
        
    3. templates
    
        模板文件夹
    
4. 基于jinja2实现模板的渲染

    后端生成好数据,通过某种方式传递给前端页面使用(前端页面可以基于模板语法更加快捷简便使用后端传过来的数据
    
5. 动静态网页

    1. 静态网页

        数据是写死的,万年不变

    2. 动态网页

        数据动态获取
    
        比如:
    
            1. 后端实时获取当前时间给前端页面渲染
    
            2. 后端从数据库获取数据给前端页面渲染

Guess you like

Origin www.cnblogs.com/binyuanxiang/p/11992816.html