zoukankan      html  css  js  c++  java
  • 学习Django框架前的预热知识

    一、先写一个web框架,也就是后端服务器

    1、服务端代码

    import socket
    
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)   # 如果为空默认为TCP
    server.bind(("127.0.0.1",9000))
    server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    server.listen(5)
    
    while True:
        conn,addr = server.accept()
        data = conn.recv(1024)
        print(data)     #先研究这个data
        conn.send(b"HTTP1.1 200 ok
    
     Hello world")    #加http协议的回应头,和回应码,注意
    
    不能少
        conn.close()

    2、客户端浏览器访问这个web服务端

    访问时加不同的后缀,之后查看服务端

    http://127.0.0.1:9000/index

    http://127.0.0.1:9000/login

    3、查看服务端

    """
    b'GET /index HTTP/1.1
    
    Host: 127.0.0.1:9000
    
    Connection: keep-alive
    
    Upgrade-Insecure-Requests: 1
    
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36
    
    Sec-Fetch-Dest: document
    
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,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
    
    Accept-Encoding: gzip, deflate, br
    
    Accept-Language: zh-CN,zh;q=0.9
    
    '
    """
    """
    b'GET /login HTTP/1.1
    
    Host: 127.0.0.1:9000
    
    Connection: keep-alive
    
    Upgrade-Insecure-Requests: 1
    
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.116 Safari/537.36
    
    Sec-Fetch-Dest: document
    
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,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
    
    Accept-Encoding: gzip, deflate, br
    
    Accept-Language: zh-CN,zh;q=0.9
    
    '
    """

     注意:我们只看圈出来的,那两个/favicon.ico我们不关注

    通过服务端接收我们发现,在访问时加的后缀时圈出来的数据第二个字段

    二、根据需求一步步接近Django

    需求一:

    根据客户端浏览器输入时添加的不同后缀,服务端返回不同的内容

    例如:

    客户端浏览器输入http://127.0.0.1:9000/index;服务端返回index

    实现:

    根据一中我们已经直到,浏览器输入的后缀可以在服务端接收的data获取到,就是data的第二个字段;so,服务端接收到data后可以对data字符串进行decode("utf-8")解码,之后split切割,搞成列表,这样后缀就是获取到的列表索引为1的元素

    代码:

    import socket
    
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)   # 如果为空默认为TCP
    server.bind(("127.0.0.1",9000))
    server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    server.listen(5)
    
    while True:
        conn,addr = server.accept()
        data = conn.recv(1024)
        data=data.decode("utf-8")   #字符串
        current_path = data.split()[1]   #取到后缀
        # print(current_path)
        #发回应头和回应码
        conn.send(b"HTTP1.1 200 ok
    
    ")   #和要发的内容分开,分两次发
        #拿到路径后进行判断
        if current_path == "/index":
            conn.send(b"This is index ")
        elif current_path == "/login":
            conn.send(b"This is login ")
        elif current_path == "/":
            conn.send(b"hello web ")
        else:
            conn.send(b"404")
        conn.close()

    需求二:根据输入返回html页面

     代码:

    import socket
    
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)   # 如果为空默认为TCP
    server.bind(("127.0.0.1",9000))
    server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    server.listen(5)
    
    while True:
        conn,addr = server.accept()
        data = conn.recv(1024)
        data=data.decode("utf-8")   #字符串
        current_path = data.split()[1]   #取到后缀
        # print(current_path)
        #发回应头和回应码
        conn.send(b"HTTP1.1 200 ok
    
    ")   #和要发的内容分开,分两次发
        #拿到路径后进行判断
        if current_path == "/index":
            with open("index.html","rb") as f:
                conn.send(f.read())
        elif current_path == "/login":
            conn.send(b"This is login ")
        elif current_path == "/":
            conn.send(b"hello web ")
        else:
            conn.send(b"404")
        conn.close()

    总结:纯手撸版本的不足之处

    #不足之处
      1.代码重复(服务端代码所有人都要重复写)
      2.手动处理http格式的数据 并且只能拿到url后缀 其他数据获取繁琐(数据格式一样处理的代码其实也大致一样 重复写)
      3.并发的问题

    基于wsgiref模块实现上面的需求

    """
    urls.py               路由与视图函数对应关系
    views.py              视图函数(后端业务逻辑)
    templates文件夹        专门用来存储html文件
    """
    # 按照功能的不同拆分之后 后续添加功能只需要在urls.py书写对应关系然后取views.py书写业务逻辑即可

    目录:

    基于wsgrief模块web框架.py代码:

    from wsgiref.simple_server import make_server
    
    def run(env,response):
        """
        两个模块加括号调用传过来的参数env,response以及return解释:
        :param env:请求相关的所有数据
        :param response:响应相关的所有数据
        :return:返回给浏览器的数据,和socket一样传输要转成二进制格式
        """
        # print(env)    #根据env的大字典,可以发现,浏览器输入的后缀在大字典中的key为'PATH_INFO'
        """
        env是一个大字典,字典包含了请求里面的所有数据,还封装了一些其他数据
        (这个工作是wsgrief模块做的,帮我们处理好http格式的数据 封装成了字典,让你更加方便的去操作)
        """
        response("200 ok",[])   #响应首行,加响应头[],列表内为空就行
    
        current_path = env.get('PATH_INFO')   #取到后缀路径
        # 拿到路径后进行判断
        if current_path == "/index":
            with open("index.html", "rb") as f:
                return [f.read()]       # 写法固定,返回数据用列表包起来
        elif current_path == "/login":
            return [b"login"]
        elif current_path == "/":
            return [b"hello web"]
        else:
            return [b"404 heihei"]
    
    
    if __name__ == '__main__':
        """ 
        会实时监听127.0.0.1:8080地址 只要有客户端来了都会交给run函数处理(模块会加括号触发run函数的运行) 
        注意:在加括号调用run函数的时候模块会自动传入两个参数(env,response)
        """
        server = make_server("127.0.0.1",9000,run)  #这个函数有个server返回值要接收一下
        server.serve_forever()   #启动服务端

     

    基于wsgiref模块实现需求后代码进行封装

    # 开发人员: alias
    # 开发时间: 2020/5/22 18:58
    # 文件名称: 基于wsgrief模块web框架.py
    # 开发工具: PyCharm
    from wsgiref.simple_server import make_server
    
    #访问路径为/index的处理函数
    def index(env):
        # 拿到路径后进行判断
        with open("index.html", "rb") as f:
            return f.read().decode("utf-8")  # 先解码,下面return再统一编码
    
    
    #访问路径为/login的处理函数
    def login(env):
        return "This is login"
    
    #访问路径不存在的处理函数
    def error(env):
        return "404"
    
    #url与函数的对应关系
    urls = [
        ("/index",index),
        ("/login",login),
    ]
    
    def run(env,response):
        """
        两个模块加括号调用传过来的参数env,response以及return解释:
        :param env:请求相关的所有数据
        :param response:响应相关的所有数据
        :return:返回给浏览器的数据
        """
        # print(env)    #根据env的大字典,可以发现,浏览器输入的后缀在大字典中的key为'PATH_INFO'
        """
        env是一个大字典,字典包含了请求里面的所有数据,还封装了一些其他数据
        (这个工作是wsgrief模块做的,帮我们处理好http格式的数据 封装成了字典,让你更加方便的去操作)
        """
        response("200 ok",[])   #响应首行,加响应头[],列表内为空就行
        current_path = env.get('PATH_INFO')   #取到后缀路径
    
        # 定义一个变量,存储匹配到的函数名
        func = None
        for url in urls:    #这个url就是一个个元组
            if current_path == url[0]:
                #将url对应的函数名赋值给func
                func = url[1]
                #匹配到之后结束循环
                break
    
        # 判断func是否为None
        if func:
            res=func(env)    #将env一同传给函数接收的好处,功能更加强调,方便函数对字典进行各种操作
        else:
            res=error(env)
    
        #返回数据
        return [res.encode("utf-8")]  # 写法固定,返回数据用列表包起来
    
    if __name__ == '__main__':
        """ 
        会实时监听127.0.0.1:8080地址 只要有客户端来了都会交给run函数处理(模块会加括号触发run函数的运行) 
        注意:在加括号调用run函数的时候模块会自动传入两个参数(env,response)
        """
        server = make_server("127.0.0.1",9000,run)  #这个函数有个server返回值要接收一下
        server.serve_forever()   #启动服务端

    进一步对wsgrief实现的功能代码进行拆分(因为代码多后会比较乱,所以将功能拆分成不同的文件)

     文件说明:

    # urls.py:存放url和处理函数的对应关系
    # views.py:存放处理函数
    # 基于wsgrief模块web框架.py: 入口文件
    # index.html:处理函数返回给前端的html文件

    urls.py

    """
    存放url和处理函数的对应关系
    """
    #url与函数的对应关系
    urls = [
        ("/index",index),
        ("/login",login),
    ]

    views.py

    """
    存放处理函数
    """
    #访问路径为/index的处理函数
    def index(env):
        # 拿到路径后进行判断
        with open("index.html", "r" , encoding="utf-8") as f:
            return f.read()
    
    #访问路径为/login的处理函数
    def login(env):
        return "This is login"
    
    #访问路径不存在的处理函数
    def error(env):
        return "404"

    基于wsgrief模块web框架.py

    from wsgiref.simple_server import make_server
    from urls import urls
    from views import *
    
    def run(env,response):
        """
        两个模块加括号调用传过来的参数env,response以及return解释:
        :param env:请求相关的所有数据
        :param response:响应相关的所有数据
        :return:返回给浏览器的数据
        """
        # print(env)    #根据env的大字典,可以发现,浏览器输入的后缀在大字典中的key为'PATH_INFO'
        """
        env是一个大字典,字典包含了请求里面的所有数据,还封装了一些其他数据
        (这个工作是wsgrief模块做的,帮我们处理好http格式的数据 封装成了字典,让你更加方便的去操作)
        """
        response("200 ok",[])   #响应首行,加响应头[],列表内为空就行
        current_path = env.get('PATH_INFO')   #取到后缀路径
    
        # 定义一个变量,存储匹配到的函数名
        func = None
        for url in urls:    #这个url就是一个个元组
            if current_path == url[0]:
                #将url对应的函数名赋值给func
                func = url[1]
                #匹配到之后结束循环
                break
    
        # 判断func是否为None
        if func:
            res=func(env)    #将env一同传给函数接收的好处,功能更加强调,方便函数对字典进行各种操作
        else:
            res=error(env)
    
        #返回数据
        return [res.encode("utf-8")]  # 写法固定,返回数据用列表包起来
    
    if __name__ == '__main__':
        """ 
        会实时监听127.0.0.1:8080地址 只要有客户端来了都会交给run函数处理(模块会加括号触发run函数的运行) 
        注意:在加括号调用run函数的时候模块会自动传入两个参数(env,response)
        """
        server = make_server("127.0.0.1",9000,run)  #这个函数有个server返回值要接收一下
        server.serve_forever()   #启动服务端

    更进一步对wsgrief实现的功能代码进行拆分(考虑当文件比较多的时候,使用文件夹进行划分)

    目录:

    首先文件说明:

    """
    urls.py               路由与视图函数对应关系
    views.py              视图函数(后端业务逻辑)
    templates文件夹        专门用来存储html文件
    """
    # 按照功能的不同拆分之后 后续添加功能只需要在urls.py书写对应关系然后取views.py书写业务逻辑即可

    urls.py

    """
    存放url和处理函数的对应关系
    """
    #url与函数的对应关系
    urls = [
        ("/index",index),
        ("/login",login),
    ]
    urls.py

    views.py

    """
    存放处理函数
    """
    #访问路径为/index的处理函数
    def index(env):
        # 拿到路径后进行判断
        with open("./templats/index.html", "r", encoding="utf-8") as f:
            return f.read()
    
    #访问路径为/login的处理函数
    def login(env):
        with open("./templats/login.html", "r", encoding="utf-8") as f:
            return f.read()
    
    #访问路径不存在的处理函数
    def error(env):
        return "404"
    views.py

    基于wsgrief模块web框架.py

    from wsgiref.simple_server import make_server
    from urls import urls
    from views import *
    
    def run(env,response):
        """
        两个模块加括号调用传过来的参数env,response以及return解释:
        :param env:请求相关的所有数据
        :param response:响应相关的所有数据
        :return:返回给浏览器的数据
        """
        # print(env)    #根据env的大字典,可以发现,浏览器输入的后缀在大字典中的key为'PATH_INFO'
        """
        env是一个大字典,字典包含了请求里面的所有数据,还封装了一些其他数据
        (这个工作是wsgrief模块做的,帮我们处理好http格式的数据 封装成了字典,让你更加方便的去操作)
        """
        response("200 ok",[])   #响应首行,加响应头[],列表内为空就行
        current_path = env.get('PATH_INFO')   #取到后缀路径
    
        # 定义一个变量,存储匹配到的函数名
        func = None
        for url in urls:    #这个url就是一个个元组
            if current_path == url[0]:
                #将url对应的函数名赋值给func
                func = url[1]
                #匹配到之后结束循环
                break
    
        # 判断func是否为None
        if func:
            res=func(env)    #将env一同传给函数接收的好处,功能更加强调,方便函数对字典进行各种操作
        else:
            res=error(env)
    
        #返回数据
        return [res.encode("utf-8")]  # 写法固定,返回数据用列表包起来
    
    if __name__ == '__main__':
        """ 
        会实时监听127.0.0.1:8080地址 只要有客户端来了都会交给run函数处理(模块会加括号触发run函数的运行) 
        注意:在加括号调用run函数的时候模块会自动传入两个参数(env,response)
        """
        server = make_server("127.0.0.1",9000,run)  #这个函数有个server返回值要接收一下
        server.serve_forever()   #启动服务端
    基于wsgrief模块web框架.py

    动静态网页

    """
    静态网页
        页面上的数据是直接写死的 万年不变
    动态网页
        数据是实时获取的
        eg:
            1.后端获取当前时间展示到html页面上
            2.数据是从数据库中获取的展示到html页面上
    """

    制作动态网页

    1、后端获取当前时间展示到html页面上(使用比较low的方法)

    基于wsgrief模块web框架.py,这个接口文件不变

    from wsgiref.simple_server import make_server
    from urls import urls
    from views import *
    
    def run(env,response):
        """
        两个模块加括号调用传过来的参数env,response以及return解释:
        :param env:请求相关的所有数据
        :param response:响应相关的所有数据
        :return:返回给浏览器的数据
        """
        # print(env)    #根据env的大字典,可以发现,浏览器输入的后缀在大字典中的key为'PATH_INFO'
        """
        env是一个大字典,字典包含了请求里面的所有数据,还封装了一些其他数据
        (这个工作是wsgrief模块做的,帮我们处理好http格式的数据 封装成了字典,让你更加方便的去操作)
        """
        response("200 ok",[])   #响应首行,加响应头[],列表内为空就行
        current_path = env.get('PATH_INFO')   #取到后缀路径
    
        # 定义一个变量,存储匹配到的函数名
        func = None
        for url in urls:    #这个url就是一个个元组
            if current_path == url[0]:
                #将url对应的函数名赋值给func
                func = url[1]
                #匹配到之后结束循环
                break
    
        # 判断func是否为None
        if func:
            res=func(env)    #将env一同传给函数接收的好处,功能更加强调,方便函数对字典进行各种操作
        else:
            res=error(env)
    
        #返回数据
        return [res.encode("utf-8")]  # 写法固定,返回数据用列表包起来
    
    if __name__ == '__main__':
        """ 
        会实时监听127.0.0.1:8080地址 只要有客户端来了都会交给run函数处理(模块会加括号触发run函数的运行) 
        注意:在加括号调用run函数的时候模块会自动传入两个参数(env,response)
        """
        server = make_server("127.0.0.1",9000,run)  #这个函数有个server返回值要接收一下
        server.serve_forever()   #启动服务端
    基于wsgrief模块web框架.py

    urls.py里面添加路由

    from views import *
    
    """
    存放url和处理函数的对应关系
    """
    #url与函数的对应关系
    urls = [
        ("/index",index),
        ("/login",login),
        ("/get_time",get_time),
    ]

    views.py里面添加视图函数

    import time
    
    """
    存放处理函数
    """
    #访问路径为/index的处理函数
    def index(env):
        # 拿到路径后进行判断
        with open("./templates/index.html", "r", encoding="utf-8") as f:
            return f.read()
    
    #访问路径为/login的处理函数
    def login(env):
        with open("./templates/login.html", "r", encoding="utf-8") as f:
            return f.read()
    
    #访问路径不存在的处理函数
    def error(env):
        return "404"
    
    #获取当前时间,展示到前端
    def get_time(env):
        #先获取当前时间
        current_time = time.strftime("%Y-%m-%d %X")
        #如何将后端获取到的数据传递给html文件
        with open("./templates/mytime.html","r",encoding="utf-8") as f:
            data = f.read()
        data = data.replace("dadfafdadfa",current_time)
        return  data

    mytime.html:返回的前端页面

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>mytime</title>
    </head>
    <body>
    <!--随便写的字符串用于替换成当前时间-->
    dadfafdadfa
    </body>
    </html>

    2、将一个字典传递给html文件 并且可以在文件上方便快捷的操作字典数据(使用模板语法:Jinja2模块)

    jinja2模块安装方法:

    #pip3 install jinja2

    目录:

     基于wsgrief模块web框架.py,这个接口文件不变

    import time
    from jinja2 import Template
    
    """
    存放处理函数
    """
    #访问路径为/index的处理函数
    def index(env):
        # 拿到路径后进行判断
        with open("./templates/index.html", "r", encoding="utf-8") as f:
            return f.read()
    
    #访问路径为/login的处理函数
    def login(env):
        with open("./templates/login.html", "r", encoding="utf-8") as f:
            return f.read()
    
    #访问路径不存在的处理函数
    def error(env):
        return "404"
    
    #获取当前时间,展示到前端
    def get_time(env):
        #先获取当前时间
        current_time = time.strftime("%Y-%m-%d %X")
        #如何将后端获取到的数据传递给html文件
        with open("./templates/mytime.html","r",encoding="utf-8") as f:
            data = f.read()
        data = data.replace("dadfafdadfa",current_time)
        return  data
    
    #获取字典
    def get_dict(env):
        #定义一个字典用于发往html文件
        user_dic = {"username":"egon","age":18}
        with open("./templates/get_dict.html","r",encoding="utf-8") as f:
            data = f.read()
        tmp = Template(data)     # 将html文件读出来的data放入Template之后赋给变量tmp,之后就可以给这个html文件传值了
    
        # 给get_dict.html传递了一个值,get_dict.html页面内部通过变量名user就能拿到user_dic
        res = tmp.render(user=user_dic)
    
        return res
    基于wsgrief模块web框架.py

    urls.py添加路由

    from views import *
    
    """
    存放url和处理函数的对应关系
    """
    #url与函数的对应关系
    urls = [
        ("/index",index),
        ("/login",login),
        ("/get_time",get_time),
        ("/get_dict",get_dict),   #添加get_dict路由关系
    ]

    views.py添加视图函数

    import time
    from jinja2 import Template  
    
    """
    存放处理函数
    """
    #访问路径为/index的处理函数
    def index(env):
        # 拿到路径后进行判断
        with open("./templates/index.html", "r", encoding="utf-8") as f:
            return f.read()
    
    #访问路径为/login的处理函数
    def login(env):
        with open("./templates/login.html", "r", encoding="utf-8") as f:
            return f.read()
    
    #访问路径不存在的处理函数
    def error(env):
        return "404"
    
    #获取当前时间,展示到前端
    def get_time(env):
        #先获取当前时间
        current_time = time.strftime("%Y-%m-%d %X")
        #如何将后端获取到的数据传递给html文件
        with open("./templates/mytime.html","r",encoding="utf-8") as f:
            data = f.read()
        data = data.replace("dadfafdadfa",current_time)
        return  data
    
    #获取字典
    def get_dict(env):
        #定义一个字典用于发往html文件
        user_dic = {"username":"egon","age":18}
        with open("./templates/get_dict.html","r",encoding="utf-8") as f:
            data = f.read()
        tmp = Template(data)     # 将html文件读出来的data放入Template之后赋给变量tmp,之后就可以给这个html文件传值了
    
        # 给get_dict.html传递了一个值,get_dict.html页面内部通过变量名user就能拿到user_dic,在get_dict.html页面内部怎么引用见get_dict,html
        res = tmp.render(user=user_dic)
    
        return res

    get_dict.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>get_dict</title>
    </head>
    <body>
        <!--两个大括号,里面加上视图函数传递过来的变量名,这个变量名就对应那个字典user_dic-->
        {{ user }}
        <!--可以很方便的控制绑定过来的字典,例如字典取值,有三种方式-->
        {{ user.get("username") }}
        {{ user.age }}
        {{ user["username"] }}
    
    </body>
    </html>

    浏览器访问

     

    实践:后端获取数据库中的数据进行前端展示

    准备一下数据库:

     目录:

     基于wsgrief模块web框架.py,这个接口文件不变

    from wsgiref.simple_server import make_server
    from urls import urls
    from views import *
    
    def run(env,response):
        """
        两个模块加括号调用传过来的参数env,response以及return解释:
        :param env:请求相关的所有数据
        :param response:响应相关的所有数据
        :return:返回给浏览器的数据
        """
        # print(env)    #根据env的大字典,可以发现,浏览器输入的后缀在大字典中的key为'PATH_INFO'
        """
        env是一个大字典,字典包含了请求里面的所有数据,还封装了一些其他数据
        (这个工作是wsgrief模块做的,帮我们处理好http格式的数据 封装成了字典,让你更加方便的去操作)
        """
        response("200 ok",[])   #响应首行,加响应头[],列表内为空就行
        current_path = env.get('PATH_INFO')   #取到后缀路径
    
        # 定义一个变量,存储匹配到的函数名
        func = None
        for url in urls:    #这个url就是一个个元组
            if current_path == url[0]:
                #将url对应的函数名赋值给func
                func = url[1]
                #匹配到之后结束循环
                break
    
        # 判断func是否为None
        if func:
            res=func(env)    #将env一同传给函数接收的好处,功能更加强调,方便函数对字典进行各种操作
        else:
            res=error(env)
    
        #返回数据
        return [res.encode("utf-8")]  # 写法固定,返回数据用列表包起来
    
    if __name__ == '__main__':
        """ 
        会实时监听127.0.0.1:8080地址 只要有客户端来了都会交给run函数处理(模块会加括号触发run函数的运行) 
        注意:在加括号调用run函数的时候模块会自动传入两个参数(env,response)
        """
        server = make_server("127.0.0.1",9000,run)  #这个函数有个server返回值要接收一下
        server.serve_forever()   #启动服务端
    wsgrief模块web框架.py

    urls.py添加路由

    from views import *
    
    """
    存放url和处理函数的对应关系
    """
    #url与函数的对应关系
    urls = [
        ("/index",index),
        ("/login",login),
        ("/get_time",get_time),
        ("/get_dict",get_dict),
        ("/get_user",get_user),
    ]

    views.py添加视图函数

    import time
    from jinja2 import Template
    import pymysql
    """
    存放处理函数
    """
    #访问路径为/index的处理函数
    def index(env):
        # 拿到路径后进行判断
        with open("./templates/index.html", "r", encoding="utf-8") as f:
            return f.read()
    
    #访问路径为/login的处理函数
    def login(env):
        with open("./templates/login.html", "r", encoding="utf-8") as f:
            return f.read()
    
    #访问路径不存在的处理函数
    def error(env):
        return "404"
    
    #获取当前时间,展示到前端
    def get_time(env):
        #先获取当前时间
        current_time = time.strftime("%Y-%m-%d %X")
        #如何将后端获取到的数据传递给html文件
        with open("./templates/mytime.html","r",encoding="utf-8") as f:
            data = f.read()
        data = data.replace("dadfafdadfa",current_time)
        return  data
    
    #获取字典
    def get_dict(env):
        #定义一个字典用于发往html文件
        user_dic = {"username":"egon","age":18}
        with open("./templates/get_dict.html","r",encoding="utf-8") as f:
            data = f.read()
        tmp = Template(data)     # 将html文件读出来的data放入Template之后赋给变量tmp,之后就可以给这个html文件传值了
    
        # 给get_dict.html传递了一个值,get_dict.html页面内部通过变量名user就能拿到user_dic
        res = tmp.render(user=user_dic)
    
        return res
    
    def get_user(env):
        #去数据库中获取数据,传递给html页面,借助于模板语法 发送给浏览器
        # 链接
        conn = pymysql.connect(
            host='127.0.0.1',
            port=3306,
            user='root',
            password='123456',
            database='atm_db',
            charset='utf8',
            # autocommit=True    # 自动提交
        )
        # 游标
        cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)   #执行完毕返回的结果集以字典显示
    
        # 执行sql语句
        sql = 'select * from userinfo'
        rows = cursor.execute(sql)  # 执行sql语句,返回sql查询成功的记录数目
        # 获取数据:
        data_list = cursor.fetchall()   # [{},{},,,,]列表套字典格式
        cursor.close()
        conn.close()
    
        #将获取到的数据传递给html文件
        with open("./templates/user_info.html", "r", encoding="utf-8") as f:
            data = f.read()
        tmp = Template(data)
        # 给user_info.html传递了一个值,user_info.html页面内部通过变量名user_data就能拿到data_list
        res = tmp.render(user_data=data_list)
    
        return res

    user_info.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>userinfo</title>
        <!-- Bootstrap3 核心 CSS 文件 -->
        <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    
        <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
        <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
    
        <!-- Bootstrap3 核心 JavaScript 文件 -->
        <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
        <!-- <link rel="stylesheet" href="css/font-awesome.min.css"> -->
        <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
    </head>
    <body>
        <div class="container">
            <div class="row">
                <div class="col-md-8 col-md-offset-2">
                    <h1 class="text-center">用户数据</h1>
                    <br/>
                    <table class="table table-striped table-hover">
                        <thead>
                            <tr>
                                <th  class="text-center">ID</th>
                                <th  class="text-center">username</th>
                                <th  class="text-center">password</th>
                                <th  class="text-center">balance</th>
                                <th  class="text-center">flow</th>
                            </tr>
                        </thead>
                        <tbody>
                            {% for user_dict in user_data %}
                                <tr>
                                    <td>{{ user_dict.id}}</td>
                                    <td>{{ user_dict.username}}</td>
                                    <td>{{ user_dict.password}}</td>
                                    <td>{{ user_dict.balance}}</td>
                                    <td>{{ user_dict.flow}}</td>
                                </tr>
                            {% endfor %}
                        </tbody>
                    </table>
                </div>>
            </div>
        </div>
    </body>
    </html>

    浏览器访问效果:

     总结:jinja2使用

    # pip3 install jinja2    # 安装方法
    """模版语法是在后端起作用的"""
    
    # 模版语法(非常贴近python语法)
    {{ user }}
    {{ user.get('username')}}  #获取值
    {{ user.age }}
    {{ user['hobby'] }}
    
    # 模板语法支持for循环
    {% for user_dict in user_data %}
        <tr>
            <td>{{ user_dict.id}}</td>
            <td>{{ user_dict.username}}</td>
            <td>{{ user_dict.password}}</td>
            <td>{{ user_dict.balance}}</td>
            <td>{{ user_dict.flow}}</td>
        </tr>
    {% endfor %}

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

    """
    wsgiref模块做的两件事
        1.请求来的时候解析http格式的数据 封装成大字典
        2.响应走的时候给数据打包成符合http格式 再返回给浏览器
    
    """

     

     解释

    CGI:定义了客户端浏览器与服务器之间如何传数据
    FastCGI: CGI的升级版
    WSGI:为Python定义的web服务器和web框架之间的接口标准
    uWSGI:一个Web Server,即一个实现了WSGI的服务器,大体和Apache是一个类型的东西,处理发来的请求
    uwsgi: uWSGI自有的一个协议
  • 相关阅读:
    delphi private public protected
    delphi 程序流程控制
    TTrayIcon-Delphi系统托盘组件
    如果没有你-莫文蔚
    ShellExecute 调用bat文件
    delphi ShellExecute使用
    delphi 测试ping
    centos7 安装redis
    my.cnf 基础配置
    Delphi的类和对象(七)- 继承
  • 原文地址:https://www.cnblogs.com/baicai37/p/12939491.html
Copyright © 2011-2022 走看看