zoukankan      html  css  js  c++  java
  • 引入web框架以及优化过程

    简单的web框架搭建

    软件开发目录规范

    1. C/S架构
    2. B/S架构

    ps: B/S架构的本质就是一个C/S结构

    搭建web框架

    我们都知道如果我们想开发一个B/S的架构的软件,就必须要依赖于浏览器.

    而为了让我们的页面能够被浏览器识别,我们就必须得遵循别人的协议标准.

    当然你也可以不遵循,但是你得自己开发一个客户端,用于你自己的服务器上,要是你这个需求量也很大,别人都要下载你的客户端程序,而不是浏览器,当然它们就可以遵循你的标准协议使用了.

    那么我们就可以想到有一个现成的客户端,并且功能还那么强大,我们就没必要重复造轮子了.

    所有我们就基于浏览器去开发服务器就好了.

    那么这个浏览器的协议是什么呢??

    HTTP协议

    我们就从http协议开始入手

    http协议有四大特点

    1. 它是基于TCP/IP协议中的应用层,是在我们的应用程序中的协议

    2. 它是基于请求响应的协议

      什么意思?

      我们要知道我们的浏览器是一个“超级”客户端,在浏览器的网址栏中输入一个url就是一个请求,而服务端收到请求就会有一个响应去回复浏览器的请求信息.

      都是客户端去和服务端发送请求的

    3. 无状态的

      就是它不会记住你的服务器状态,你每一次来它都当作你是第一次来,并不会因为你来了几次就记住你

      就好比说纵然见你千百遍,我却始终待你如初见.

      这可得讲讲它的历史了,以前的浏览器啊,里面打开一个网页就是一写文章和报纸一样的,但是随着互联网慢慢的发展,报纸格式也就是说全文字的网页以及满足不了用户了,就变成了现在的支付宝啊,淘宝啊.这个在我们使用的过程中.我们是不是登录了下次就不用登录啦.你淘宝里面的购物车信息,下次登录还在.还有那个扫描二维码登录的.

      这都是为了解决无连接的.我们会用到cookie,session.和taken技术了.这都可以起到保存我们的用户状态的作用.

    4. 短链接&无链接

      就是每次浏览器和服务器连接之后,默认都是交互完毕之后就自动断开连接了.所有我们每次操作浏览器都会有很多的次的断开连接,再断再连的操作过程.

      而还有一种就是长连接:

      顾名思义,长连接就是一个默认不会断开俩者之间连接的.一般可以基于websocket实现.这个实现的还可以让服务器端给你浏览器发送请求. 就比如一写小网站些弹出广告啊,那些的.

    那了解了http的四大特性,里面什么是请求什么是响应?

    什么是响应

    请求就是浏览器向服务器发送get/post请求,接收/上传 服务器的数据

    响应就是服务器接收到客户端的请求信息,给予的回应,比如返回 一个 200 ok 的页面信息

    我们再讲讲http的组成,为了方便管理和处理,我们的请求格式和响应格式组成的方式是差不多一样的.

    请求格式

    1. 请求首行: =====> http的版本信息 和请求方式
    2. 请求头部 ====> 放的是一堆客户端的信息字典,一大堆的k,v键值对
    3. /r/n/
    4. 请求体 (并不是所有的请求方式都有,get没有post有,post存放的是一些提交的敏感数据,比如说账号和密码)

    请求格式图解

    img

    http 响应格式

    响应首行 ====> 标识http协议的版本, 响应状态码

    响应头 ===== > 一大堆k,v键值对

    /r/n

    响应体 =====> 返回给浏览器展示给用户看的数据.

    响应格式图解:

    img

    介绍网络名词

    请求方式:

    1.get请求

    • 朝服务器要数据
    • eg:输入url获取对应的数据

    2.post请求

    • 朝服务器提交数据
    • eg: 用户登录,向服务器提交用户名和密码数据 后端接收到数据就那些校验

    3.get请求和post请求的区别

    • get请求发送的数据是在url中携带的,以?分割url和数据,并且数据与数据之间以&符号链接,所以是暴露在网页中的

    • post请求发送的数据是在一个data的字典对象数据包里面的中,是另外存储的,并且是有加密手段的,更加的安全

      • eg:
    • get请求不如post请求安全,但一般的网络请求都是get.post一般用于敏感数据.

    url

    定义为: 统一资源定位符

    格式:scheme:[//[user:password@]host:[:port][/]path[?query-string][#anchor]

    参数介绍:

    • scheme:协议(例如:http/https/ftp.等)
    • user:password@ 用户的登录名和密码
    • host:服务器的ip地址或者域名
    • port: 服务器的端口号 (如果用的是协议,比如http(默认端口80),https(默认端口为443))
    • path: 访问资源的路径
    • query-string: 参数,一般为客户端发送给服务端的数据
    • anchor:锚(跳转到指定的锚点位置)

    例如:url: https://www.cnblogs.com/jkeykey/p/14521413.html

    对应关系

    • scheme: https
    • host:www.cnblogs.com
    • port: 443
    • path: /jkeyjkey/p/14521413.html

    开始推理web框架

    介绍了http的相关知识,现在我们终于可以搭建我们的web框架了

    未遵循浏览器标准

    未遵循浏览器标准的代码如下:

    mport socket
    
    server = socket.socket()
    server.bind(('127.0.0.1', 8080))
    server.listen(5)
    
    
    while True:
        conn, client_addr = server.accept()
        data_bytes = conn.recv(8192)
        print(data_bytes)  # 将浏览器发来的消息打印出来
        """
        ===================== HTTP协议的请求数据格式4部份 =====================
        b'GET / HTTP/1.1
           # 请求首行(标识HTTP协议版本,当前请求方式)
        Host: 127.0.0.1:8080
       # 请求头(一大堆k,v键值对)
        Connection: keep-alive
    
        Upgrade-Insecure-Requests: 1
    
        User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36
    
        Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
    
        Accept-Encoding: gzip, deflate, br
    
        Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
    
        
    '      # 
    
                   # 请求体(并不是所有的请求方式都有. get没有post有, post存放的是请求提交的敏感数据)
                   
        b''               
        """
        conn.send(b'ok')
        conn.close()
    

    我们这样如果是用自己的客户端,发送回收打印是可以的.但是如果在浏览器中打开,是查看不到ok这个字段的.

    那如何才能在浏览器上显示我们的内容,或者说html文件呢?

    这就要看看浏览器的格式了.

    我们以访问博客园服务器为例

    我们访问: https://www.cnblogs.com/

    右键检查,点击network,然后刷新一下页面,抓取到网页的数据包信息

    响应相关信息可以在浏览器调试窗口的network标签页中看到。

    img

    点击view source之后显示如下图:

    img

    那我们知道了,响应格式

    遵循http协议

    那我们的代码就应该也要遵循他的协议

    代码改成

    import socket
    
    server = socket.socket()
    
    server.bind(("127.0.0.1", 8080))
    
    server.listen(5)
    
    
    while True:
    
        conn,addr = server.accept()
    
        data_bytes = conn.recv(1024)
        print(data_bytes)
    	
        # 先发送我们的格式的首行信息和 相应状态 以及换行.
        # 为什么是俩个 
    ,那是因为第一个
    是状态码的换行,第二个才是与代码体的换行
        conn.send(b"http/1.1 200 ok 
    
    ")
        conn.send(b"hello world")
    
        conn.close()
    

    客户端访问的数据格式

    b'GET / HTTP/1.1
    Host: 127.0.0.1:8080
    Connection: keep-alive
    Pragma: no-cache
    
    Cache-Control: no-cache
    
    sec-ch-ua: "Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"
    
    sec-ch-ua-mobile: ?0
    
    Upgrade-Insecure-Requests: 1
    
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36
    
    Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    
    Sec-Fetch-Site: none
    
    Sec-Fetch-Mode: navigate
    
    Sec-Fetch-User: ?1
    
    Sec-Fetch-Dest: document
    
    Accept-Encoding: gzip, deflate, br
    
    Accept-Language: zh-CN,zh;q=0.9
    
    
    '
    

    此时我们访问的页面,就可以看到我们的 hello word 信息了

    web框架之显示html文件

    然后现在我们就可以对我们的服务端进行优化了

    现在有一个需求,让我们模拟,百度冲浪,输入一个url就可以获取到对应的页面内容

    那这要怎么实现呢?

    我们可以先拿到客户端数据中的url中的页面信息

    代码演示

    import socket
    
    server = socket.socket()
    server.bind(('127.0.0.1', 8080))
    server.listen(5)
    
    while True:
        conn, client_addr = server.accept()
        data_bytes = conn.recv(8192)
        print(data_bytes)
        '''
        b'GET /index HTTP/1.1
    Host: 127.0.0.1:8080
    C
        br
    Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
    
        
    '
        '''
        path = data_bytes.split()[1]
        print(path)   # b'/index'
        conn.send(b"HTTP/1.1 200 OK
    
    ")   # 因为要遵循HTTP协议,所以回复的消息也要加状态行
        if path == b'/index':
            response = b'you can you do not bb: %s' % path
        elif path == b'/login':
            response = b'you can you not bb: %s' % path
        else:
            response = b'404	Not Found'
        conn.send(response)
        conn.close()
    

    访问index和login时

    访问一个不存在的url时

    优化web框架之urls_list

    那么这时候,问题又来了. 一个url就要对应一个if分支,那么我如果有100个呢?

    那么要写100j个if判断吗??这肯定是不行的,所以我们要通过字典或者列表来优雅的替代多分支

    代码如下

    import socket
    
    server = socket.socket()
    server.bind(('127.0.0.1', 8080))
    server.listen(5)
    
    
    # 将返回不同的内容部分封装成函数
    def index(path):
        s = "This is {} page table!".format(path)
        return s
    
    
    def login(path):
        s = "This is {} page table!".format(path)
        return s
    
    
    def error(path):
        return '404 not found: {}'.format(path)
    
    
    # 定义一个url和实际要执行的函数的对应关系
    urls = [
        ('/index', index),
        ('/login', login),
    ]
    
    while True:
        conn, client_addr = server.accept()
        data_bytes = conn.recv(8192)
        print(data_bytes)
        path = data_bytes.split()[1].decode('utf-8')  # 分离出的访问路径, 再把收到的字节类型的数据转换成字符串
        print(path)  # '/index'
        conn.send(b"HTTP/1.1 200 OK
    
    ")  # 因为要遵循HTTP协议,所以回复的消息也要加状态行
    
        func = None  # 定义一个保存将要执行的函数名的变量
        for url in urls:
            if path == url[0]:
                func = url[1]
                break
        if func:
            response = func(path)
        else:
            response = error(path)
    
        # 返回具体的响应消息
        conn.send(response.encode('utf-8'))
        print(response.encode('utf-8'))
        conn.close()
    

    后缀/index路径访问

    后缀/login

    路径不存在时

    知识点

    动静态网页

    静态网页

    静态网页就是我们之前用的前端的知识搭建的,内容是写死的,比如<p>111</p>

    用这样的标签搭建的网页就是静态网页.

    那么动态网页就是和这个相反的,标签内的内容是,即是后端获取的, 比如 <p>{{ name }}</p>,用这样的标签搭建的网页就是动态网页.

    最大的区别就是,静态的网页,不改文本的内容是不会变的,而动态页面可以通过改后端的数据来改变网页中的内容.

    静态网页详细介绍: 返回具体的html文件

    我们之前用渲染给客户端的数据都是str字符串类型的,那我们怎么讲html文件中的内容渲染到浏览器上呢?

    一样的思想,可以先将html文件中的内容全部拿到,一起发送给浏览器,让其渲染网页即可

    代码为

    import socket
    
    server = socket.socket()
    server.bind(('127.0.0.1', 8080))
    server.listen(5)
    
    def get_f(path):
        import os
        path = r"./templates"+path+".html"
        with open(path,'rb') as f:
            html_data = f.read()
            return html_data
    
    # 将返回不同的内容部分封装成函数
    def index(path):
        s = get_f(path)
        return s
    
    
    def login(path):
        s = get_f(path)
        return s
    
    
    def error(path):
        return bytes('404 not found: {}'.format(path).encode("utf-8"))
    
    
    # 定义一个url和实际要执行的函数的对应关系
    urls = [
        ('/index', index),
        ('/login', login),
    ]
    
    while True:
        conn, client_addr = server.accept()
        data_bytes = conn.recv(8192)
        print(data_bytes)
        path = data_bytes.split()[1].decode('utf-8')  # 分离出的访问路径, 再把收到的字节类型的数据转换成字符串
        print(path)  # '/index'
        conn.send(b"HTTP/1.1 200 OK
    
    ")  # 因为要遵循HTTP协议,所以回复的消息也要加状态行
    
        func = None  # 定义一个保存将要执行的函数名的变量
        for url in urls:
            if path == url[0]:
                func = url[1]
                break
        if func:
            response = func(path)
        else:
            response = error(path)
    
        # 返回具体的响应消息
        conn.send(response)
        conn.close()
    

    当为index时

    当为login时

    动态网页

    动态网页: 后端获取当前的时间展示到index.html页面上

    代码如下

    import socket
    
    server = socket.socket()
    server.bind(('127.0.0.1', 8080))
    server.listen(5)
    
    
    # 将返回不同的内容部分封装成函数
    def _open_read(filename):
        with open(filename, 'rt', encoding='utf-8') as f:
            return f.read()
    
    
    def index(path):
        return _open_read(r'.	emplatesindex.html')
    
    
    from datetime import datetime
    def login(path):   # !!!动态网页!!: 后端获取当前时间展示到html页面上
        data = _open_read(r'.	emplateslogin.html')
        data = data.replace('login', "login" + datetime.now().strftime('%Y-%m-%y %X'))
        return data
    
    
    def error(path):
        return _open_read(r'.	emplateserror.html')
    
    
    # 定义一个url和实际要执行的函数的对应关系
    urls = [
        ('/index', index),
        ('/login', login),
    ]
    
    while True:
        conn, client_addr = server.accept()
        data_bytes = conn.recv(8192)
        print(data_bytes)
        path = data_bytes.split()[1].decode('utf-8')  # 分离出的访问路径, 再把收到的字节类型的数据转换成字符串
        print(path)  # '/index'
        conn.send(b"HTTP/1.1 200 OK
    
    ")  # 因为要遵循HTTP协议,所以回复的消息也要加状态行
    
        func = None  # 定义一个保存将要执行的函数名的变量
        for url in urls:
            if path == url[0]:
                func = url[1]
                break
        if func:
            response = func(path)
        else:
            response = error(path)
    
        # 返回具体的响应消息
        conn.sendall(response.encode('utf-8'))
        print(response.encode('utf-8'))
        conn.close()
    

    优化web框架之wsgiref模块

    使用wsgiref模块代替之前 web框架的socket server 部分

    我们之前写的简单的web框架有俩个缺陷

    1. 代码重复

      服务端socket代码需要我们自己写.如果好多服务端就要写好多个socket模块的服务端

    2. http格式的数据得自己处理

      并且只能拿到url后缀 其他数据获取得通过re正则去header那个字符串里面取,太麻烦了.

    而利用wsgiref模块优势

    1. wsgiref模块帮助我们封装了socket代码
    2. 帮我们处理http格式的数据

    wsgiref模块就是一个web服务端网关接口"

    1. 请求来的时候会帮助你自动拆分http格式数据并封装成非常方便处理的数据格式 --->env大字典
    2. 响应走的时候会帮你将数据再打包成符合http格式的数据.

    ps: 所以wsgiref模块会为我们做服务器对客户端的请求和响应数据,就不需要我们指定编码和解码了.而且取数据很方便

    我们之前的代码都是写在一个文件内,我们都知道这是不允许的,所以我们应该对这些方法和代码进行区分,分文件存.

    我们总结一下,我们之前的功能除了服务器发送还有三个

    1.urls_list 一个url后缀和函数(类也可以)对应关系

    2.views url对应的函数(类)的函数书写

    3.templates 模块.存放一些html文件

    所以我们现在可以讲这三个功能查分开来

    这样做的好处是解耦合,拓展方便,只要按照 urls.py---> view.py ---->templates文件夹下的html 就可以搭建我们的web了.

    现在我们的服务端启动文件可以为

    from wsgiref.simple_server import make_server
    from views import *
    from urls import *
    
    
    def run_server(request, response):
        """
        函数定义什么都无所谓
        :param request: 请求相关的所有数据
                        是一个大字典,wsgires模块帮你处理好http格式的数据,封装成一个字典方便你的后续操作
        :param response: 响应相关的所有数据
        :return: 返回给浏览器的数据,返回的格式必须为一个二进制格式
        """
        response("200 OK", [])  # 响应首行 响应头
        print(request)
        """
        字典的其中一部分
        'PATH_INFO': '/login', 'QUERY_STRING': '', 'REMOTE_ADDR': '127.0.0.1', 'CONTENT_TYPE': 'text/plain', 'HTTP_HOST': '127.0.0.1:8080'
        """
        path_info = request.get("PATH_INFO")
        print(path_info)
    
        func = None
        for url in urls_list:
            if path_info == url[0]:
                func = url[1]
                break
        if func:
            data = func(request)
        else:
            data = error(request)
    
        return [data.encode("utf-8")]
    
    
    if __name__ == '__main__':
        server = make_server("127.0.0.1", 8080, run_server)
        """
        会实时监听 127.0.0.1:8080 地址 只要有客户端来了
        都会交给run函数处理(加括号触发run函数的运行)
        
        flask启动源码
            make_server("127.0.0.1",8080,obj)
            __call__
        """
        server.serve_forever()  # 服务器一直开启
    

    urls.py

    """
    url后缀对应函数的对应关系文件
    """
    
    from views import *
    
    
    urls_list = [
        ("/index", index),
        ("/login", login),
    
    ]
    

    views.py

    """
    函数脚本,处理url对应的函数
    """
    
    
    def _open_read(filename):
        with open(filename, 'rt', encoding='utf-8') as f:
            return f.read()
    
    
    def index(request):
        return _open_read('templates/index.html')
    
    
    def login(request):  # !!!动态网页!!: 后端获取当前时间展示到html页面上
        from datetime import datetime
        data = _open_read('templates/login.html')
        data = data.replace('login', datetime.now().strftime('%Y-%m-%y %X'))
        return data
    
    
    def error(request):
        return _open_read('templates/error.html')
    

    优化方案之jinja2模块

    到现在我们使用的网页大部分都是静态网页,动态网页也是通过python的方法

    那我们优化这种局部的渲染的.

    那就要讲到另外一个模块了jinja2,

    jinja2作用: jiaja2的原理就是字符串替换,我们只要在html页面中遵循jinja2的语法规范写上,其内部就会按照指定的语法进行相应的替换,从而达到动态的返回内容效果.

    要使用这个模块,我们得事先安装,安装了flask的不用安装,flask自动携带jinja2,默认使用的就是这个.

    安装命令:通过清华的地址,下载会快一点

    pip3 install -ihttps://pypi.tuna.tsinghua.edu.cn/simple jinja2

    jinja2的模板语法

    // 定义变量使用双花括号
    {{ 变量名称 }}  // 该变量可以是python内的所有数据类型
    
    // 执行for循环,if流程控制 为花括号内左右%
    {% for i in list %}
    {{ i.id }}  # 不仅支持python的数据类型的语法,还支持点类属性取值的方法
    {% endfor %}
    

    那我们将这个运用到我们的框架中

    使用jinja2优化网页内容

    例子: 将user表中的数据渲染到 user.html网页中

    创建user表

    create database db777  charset utf8;
    use db777
    create table user(
    	id int primary key auto_increment,
        username varchar(16),
        pwd varchar(14),
        sex enum("男","女"),
        hobbies set("吃饭","睡觉","打土匪","打劫")
    ); 
    insert into user(username,pwd,sex,hobbies) values
    ("jkey","123","男","吃饭,打土匪"),
    ("土匪","123","男","吃饭,打劫"),
     ("派大星","123","男","打土匪");
    

    执行文件不需要更改

    所以执行文件用上面的即可

    urls.py

    """
    url后缀对应函数的对应关系文件
    """
    
    from views import *
    
    
    urls_list = [
        ("/index", index),
        ("/login", login),
        ("/user", user)
    ]
    

    views.py

    """
    函数脚本,处理url对应的函数
    """
    
    
    def _open_read(filename):
        with open(filename, 'rt', encoding='utf-8') as f:
            return f.read()
    
    
    def index(request):
        return _open_read('templates/index.html')
    
    
    def login(request):  # !!!动态网页!!: 后端获取当前时间展示到html页面上
        from datetime import datetime
        data = _open_read('templates/login.html')
        data = data.replace('login', datetime.now().strftime('%Y-%m-%y %X'))
        return data
    
    
    def _open_mysql():
        import pymysql
        conn = pymysql.connect(
            host="127.0.0.1",
            port=3306,
            user="root",
            passwd="jzd123",
            db="db777",
            charset='utf8',
        )
        cursor = conn.cursor(pymysql.cursors.DictCursor)
        affected_rows = cursor.execute("select * from user;")
        if affected_rows:
            user_dict_list = cursor.fetchall()
            return user_dict_list
        else:
            print("对不起你要查找的数据不存在")
        cursor.close()
        conn.close()
    
    
    def user(request):
        from jinja2 import Template
        data = _open_read("templates/user.html")
        user_dict_list = _open_mysql()
        if user_dict_list:
            temp = Template(data)
            res = temp.render(user_dict_list=user_dict_list)
            return res
        return error(request)
    
    
    def error(request):
        return _open_read('templates/error.html')
    

    templates/user.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
        <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <title>Title</title>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <h1 class="text-center">用户表信息</h1>
            <table class="table table-hover table-striped table-bordered">
                <thead>
                <tr>
                    <th>序号</th>
                    <th>名称</th>
                    <th>密码</th>
                    <th>性别</th>
                    <th>爱好</th>
                </tr>
                </thead>
                <tbody>
                {% for user_dict in user_dict_list %}
                <tr>
                    <td> {{user_dict.id}}</td>
                    <td> {{user_dict.username}}</td>
                    <td> {{user_dict.pwd}}</td>
                    <td> {{user_dict.sex}}</td>
                    <td> {{user_dict.hobbies}}</td>
                </tr>
                {% endfor %}
                </tbody>
            </table>
        </div>
    </div>
    </body>
    </html>
    

    ps:注意,浏览器只会识别html和css以及JavaScript,这个模板解析是在python后端处理好的,变成一个html然后再发送给浏览器渲染的,不是浏览器帮我们解析的模块语法.

    致此我们的web简单的框架搭建就已经推理完毕了,这个过程最重要的就是对知识点的学习,以及整个的推导过程,代码不是很重要.重要的是推理过程.

    思想一定要想,学习起来才快

    总结

    1.自定义简易版本web框架请求流程图

    img

    服务端开启使用wsgiref模块搭建的启动文件,一般配置了就不需要改变.

    所以我们需要修改的文件以及步骤为 urls.py,views.py,templates模板下的html文件.

    其中需要注意的是views.py中获取数据库的数据,渲染到html文件中,可以传参进去,可以是任何的python数据类型,模板语法也需要注意.

    一定要敲,才能发现自己的薄弱点.

    流程图流程

    浏览器客户端.

    wsgiref模块

    • 请求来: 处理浏览器请求,解析浏览器http格式的数据,封装成大字典(PATH_INFO中存放的就是url的访问资源的路径)
    • 相应去: 将数据打包成符合http协议的格式,再返回给浏览器

    后端

    • urls.py

      ---> 找用户输入的路径有没有与视图函数对应关系的,有就去views.py内找到对应的函数

    • views.py

      功能1(静态): 视图函数找templates中的html文件,返回给wsgiref做http格式的封包处理,再返回给浏览器.

      功能2(动态):视图函数通过pymysql链接数据库,通过jinja2模板语法将数据库中的数据在templates文件夹下的html文件做一个数据的动态渲染, 最后返回给wsgiref做HTTP格式的封包处理, 再返回给浏览器.

      功能3(动态): 也可以通过jinja2模板语法对tmpelates文件夹下的html文件进行数据的动态渲染, 渲染完毕, 再经过wsgiref做HTTP格式的封包处理, 再返回给浏览器.

    基本使用流程

    # wsgiref模块: socket服务端(后端)
        from wsgiref.simple_server import make_server
    
        def run_server(request, response):
                """
                函数名定义什么都无所谓, 我们这里就用run_server.
                :param request:  请求相关的所有数据.
                    是一个大字典, wsgiref模块帮你处理好http格式的数据 封装成了字典让你更加方便的操作
                :param response: 响应相关的所有数据.
                :return: 返回给浏览器的数据, 返回个格式必须是'return [二进制格式的数据]' 这种样式
                """
                response('200 OK', [])    # 响应首行 响应头
                return [二进制格式的数据]
    
            if __name__ == '__main__':
                server = make_server(host, port, app)  # app=run_server
                server.serve_forever()
            
    # urls.py:路由与视图函数对应关系
    	urls = [(路由,视图函数)]
    
    # views.py: 视图函数
    	def 视图函数(request):
            pass
        
        # pymysql模块: socket服务端(后端)与数据库交互
        import pymysql
    
        conn = pymysql.connection(host, port, user, password, database, charset='utf8')
        cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
        affected_rows = cursor.execute(sql);
        cursor.fetchall()
        cursor.close()
        conn.close()
        
        # jinja2模块:后端与http文件交互,本质是一种替换操作
        	from jinja2 import Template
            temp = Template(data)  # data为要操作的替换的数据
            retuen temp.render(user=user_date)  #user 是传入给html页面的操作变量
        
    # templates 文件夹:管理html文件
    	html中使用jinja2模块的语法:
            定义变量: {{  user }}
            for循环/if流程 :  {% for i in user %} ... {% endfor %}
                如果i是一个对象,那么可以通过i.xx或者i[xx]来获取值.
    
  • 相关阅读:
    LeetCode 931. Minimum Falling Path Sum
    LeetCode 1. Two Sum
    LeetCode 72. Edit Distance
    命令行发送SMTP协议邮件(163邮箱)
    商品销量分析及预测系统测试心得
    商品销量预测 第一次迭代总结
    【Codeforces 126B】Password
    【Codeforces 466C】Number of Ways
    【CodeCraft-19 and Codeforces Round #537 (Div. 2) C】Creative Snap
    【Codeforces Global Round 1 E】Magic Stones
  • 原文地址:https://www.cnblogs.com/jkeykey/p/14539945.html
Copyright © 2011-2022 走看看