Python Django前奏手撸web框架 基于wsgiref的web框架

Posted tfzz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python Django前奏手撸web框架 基于wsgiref的web框架相关的知识,希望对你有一定的参考价值。

基于socke手撸web框架

# 请求首行
bGET / HTTP/1.1\r\n  #GET /index HTTP/1.1\r\n  (index)为浏览器请求地址)
# 请求头
Host: 127.0.0.1:8080\r\n
Connection: keep-alive\r\n
Cache-Control: max-age=0\r\n
Upgrade-Insecure-Requests: 1\r\n
# User-Agent用来标识是不是浏览器
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/76.0.3809.132 Safari/537.36\r\n
Sec-Fetch-Mode: navigate\r\n
Sec-Fetch-User: ?1\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n
Sec-Fetch-Site: none\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
\r\n
请求体
技术图片
import socket
server = socket.socket()
server.bind((127.0.0.1,8080))
server.listen(5)

while True:
    conn, addr = server.accept()
    data = conn.recv(1024)
    conn.send(bHTTP/1.1 200 OK\r\n\r\n)
    print(data)
    data = data.decode(utf-8)
    current_path = data.split(\r\n)[0].split( )[1]
    # print(current_path)
    if current_path == /index:
        # conn.send(b‘index‘)
        with open(rD:\python脱产10期视频\day51\01 纯手撸html文件.html,rb) as f:
            conn.send(f.read())
    elif current_path == /login:
        conn.send(blogin)
    else:
        conn.send(bhello world!)
    conn.close()
手撸版web框架

 

字符山与二进制字符串转换技巧

技术图片
data = bhello world

data = str(data,encoding=utf-8)
print(data)

data = bytes(data,encoding=utf-8)
print(data)
字符山与二进制字符串转换技巧

 

基于wsgiref(主要是方便前后端交互的软件)和jinja2(模板渲染)手撸web框架

技术图片
from wsgiref.simple_server import make_server
from 代码.urls import urls
from 代码.views import *

def run(env,response):
    """
    env是请求相关的数据
    response是响应相关的数据
    """
    # print(env)
    response(200 OK,[])
    current_path = env.get(PATH_INFO)
    # print(current_path)
    # if current_path == ‘/index‘:
    #     return [b‘index‘]
    # elif current_path == ‘/login‘:
    #     return [b‘login‘]
    # 定义一个存储函数名的标志位
    func = None
    for url in urls:
        # 判断当前url在不在元组内
        if url[0] == current_path:
            # 只要匹配上了  就把url后缀对应的函数名赋值给func
            func = url[1]
            # 一旦匹配上 应该立刻退出for循环 节省资源
            break
    # 对变量func做判断
    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)
    # 实时监测127.0.0.1:8080地址 一旦有客户端来连接 会自动加括号调用run方法
    server.serve_forever()  # 启动服务端
View Code

代码/url.py

技术图片
from 代码.views import *

urls = [
    (/index,index),
    (/login,login),
    (/reg,reg),
    (/get_time,get_time),
    (/get_user,get_user),
    (/get_db,get_db),
]
View Code

代码/views.py

技术图片
def index(env):
    return index
def login(env):
    return login
def errors(env):
    return 404 error

def reg(env):
    return reg

from datetime import datetime


def get_time(env):
    # 借助于时间模块 现在后端获取到时间数据
    current_time = datetime.now().strftime(%Y-%m-%d %X)
    with open(rtemplates/02 get_time.html,r,encoding=utf-8) as f:
        data = f.read()  # data其实就是一串字符串  仅此而已!!!
    data = data.replace($$time$$,current_time)
    return data



from jinja2 import Template
def get_user(env):
    user_dict = username:jason,password:123,hobby:[read,game,running]
    with open(rtemplates/03 get_user.html,r,encoding=utf-8) as f:
        data = f.read()
    temp = Template(data) # data为html读出来的所有字符串
    res =  temp.render(data = user_dict)  # 将user_dict传递给前端页面 前端页面通过变量名data(html页面中的data)就能够获取到该字典
    return res

import pymysql
def get_db(env):
    conn = pymysql.connect(
        host = 127.0.0.1,
        port = 3306,
        user = root,
        password = 123,
        database = day51,
        charset = utf8,
        autocommit = True
    )
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    sql = "select * from userinfo"
    affect_rows = cursor.execute(sql)
    data = cursor.fetchall()
    # print(data)
    with open(rtemplates/04 get_db.html,r,encoding=utf-8) as f:
        data1 = f.read()
    temp = Template(data1)
    res = temp.render(user_list= data)
    return res
View Code

templates

技术图片
#01 纯手撸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>
<h1>要放假了 好嗨皮</h1>
</body>
</html>

#02 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>

# 03 get_user.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>

# 04 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>
    <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</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文件

 模板渲染

  1.模板语法:前端可以使用后端语言的语法,来操作后端传过来的数据

静态网页
  数据是写死的,万年不变
动态网页
  数据不是写死的 是动态获取到的
比如:
1.后端实时获取当前时间"传递"给前端页面展示
2.后端从数据库获取数据"传递"给前端页面展示

页面渲染:后端把数据传给前端的过程,并把前端改成自己想要的样式。

总结:

技术图片
.纯手撸web框架
    1.手动书写socket代码
    2.手动处理http数据

2.基于wsgiref模块帮助我们处理scoket以及http数据
    wsgiref模块
        1.请求来的时候 解析http数据 帮你打包成一个字典传输给你 便于你操作各项数据
        2.响应走的时候 自动帮你把数据再打包成符合http协议格式的样子 再返回给前端
        
3.封装路由与视图函数对应关系  以及视图函数文件   网站用到的所有的html文件全部放在了templates文件夹下
    1.urls.py 路由与视图函数对应关系
    2.views.py  视图函数(视图函数不单单指函数 也可以是类)
    3.templates  模板文件夹

4.基于jinja2实现模板的渲染
    模板的渲染
        后端生成好数据 通过某种方式传递给前端页面使用(前端页面可以基于模板语法更加快捷简便使用后端传过来的数据)
View Code

 

以上是关于Python Django前奏手撸web框架 基于wsgiref的web框架的主要内容,如果未能解决你的问题,请参考以下文章

web框架底层原理;django介绍

Django——纯手撸简易web框架Django初识

Django---进阶0

Django---进阶0

2020Python修炼记web框架之 Django框架简介

2020Python修炼记web框架之 Django框架简介