[TOC]css
Django基础以前戏
HTTP协议(超文本协议)
四大特性
基于TCP/IP之上做用于应用层
基于请求响应
发是请求,给是响应html
无状态
不保存用户状态,连一次就给忘了前端
无链接
eg:one night lovepython
数据格式
请求格式
请求首行(请求方式,协议版本等)mysql
请求头(一大堆K:V键值对)jquery
\r\nweb
请求头(真正的数据 发post请求的时候才有 若是get请求不会有)sql
响应格式
响应首行数据库
响应头django
\r\n
响应体
响应状态码
用特定的数字表示一些数据
1xx:服务端已经接收到了你的数据 正在处理 你能够提交其余数据
2xx:服务端成功响应(200请求成功)
3xx:重定向
4xx:请求错误(404 请求资源不存在 403 拒绝访问)
5xx:(服务器内部错误(500))
请求方式
get请求
朝别人要数据
post请求
向别人提交数据(eg:用户登陆)
纯手撸web框架
- 手动书写socket
- 手动处理http格式数据
简单c/s链接
#服务端 import socket server = socket.socket() server.bind(('127.0.0.1', 8081)) server.listen(5) while True: conn,addr = server.accept() data = conn.recv(1024) conn.send(b'HTTP/1.1 200 OK\r\n\r\n') print(data) conn.send(b'hello baby') conn.close()
稍微复杂web框架
客户端请求什么,就返回什么,eg:客户端发送http://127.0.0.1:8081/index
则服务器返回给客户端index
import socket server = socket.socket() server.bind(('127.0.0.1', 8081)) server.listen(5) while True: conn,addr = server.accept() conn.send(b'HTTP/1.1 200 OK\r\n\r\n') data = conn.recv(1024) print(data) data = data.decode('utf8') current_path = data.split('\r\n')[0].split(' ')[1] print(current_path) if current_path == '/index': conn.send(b'index') #服务端还能够打开html文件,将文件中的东西显示给客户端 # with open(r'index.html', 'rb') as f: # conn.send(f.read()) else: conn.send(b'404 error') conn.close()
基于wsgiref
若是我不想写上面代码中的socket链接和里面的index等内容,客户端发送100个不一样的请求,我也不能手撸100遍啊!那也太累了吧,因此咱们就利用了wsgiref模块,帮咱们操做起来更简单和方便,咱们能够把在wsgiref.py中的必要代码写在相对应的文件内,如下是各个文件中要放的东西。
urls.py 路由与视图函数对象关系 views.py 放的是视图函数(处理业务逻辑的) templates 模板文件夹(一堆html文件)
wsgiref.py文件
from wsgiref.simple_server import make_server from urls import urls from views import * def run(env,response): """ :param env: 请求相关的全部数据 :param response: 响应相关的全部数据 :return: """ response('200 OK',[]) current_path = env.get('PATH_INFO') #env里面有 不少数据,咱们筛选有用的数据就行 # 先定义一个变量名 用来存储后续匹配到的函数名 func = None # for循环 匹配后缀 for url in urls: if current_path == url[0]: func = url[1] # 一旦匹配成功 就将匹配到的函数名赋值给func变量 break # 主动结束匹配 # 判断func是否有值 if func: res = func(env) else: res = error(env) return [res.encode('utf-8')] if __name__ == '__main__': server = make_server('127.0.0.1',8080,run) # 实时监听该地址 只要有客户端来链接 统一交给run函数去处理 server.serve_forever() # 启动服务端,永远等着客户端来链接
urls.py
from views import * urls = [ ('/index',index), #第二个是函数,若是匹配成功,就去views.py中去找相应的函数去运行 ('/login',login), ('/xxx',xxx), ]
views.py
from urls import urls def index(env): return 'index' def login(env): return 'login' def error(env): return '404 error' def xxx(env): return 'xxx'
客户端经过访问服务器获取字典
咱们这里须要用到一个模块jinja2
咱们须要先去下载这个模块from jinja2 import Template
具体了解jinja2
请点击连接https://www.cnblogs.com/yanjiayi098-001/p/11701150.html
wsgiref.py文件
from wsgiref.simple_server import make_server from urls import urls from views import * def run(env,response): """ :param env: 请求相关的全部数据 :param response: 响应相关的全部数据 :return: """ response('200 OK',[]) current_path = env.get('PATH_INFO') #env里面有 不少数据,咱们筛选有用的数据就行 # 先定义一个变量名 用来存储后续匹配到的函数名 func = None # for循环 匹配后缀 for url in urls: if current_path == url[0]: func = url[1] # 一旦匹配成功 就将匹配到的函数名赋值给func变量 break # 主动结束匹配 # 判断func是否有值 if func: res = func(env) else: res = error(env) return [res.encode('utf-8')] if __name__ == '__main__': server = make_server('127.0.0.1',8080,run) # 实时监听该地址 只要有客户端来链接 统一交给run函数去处理 server.serve_forever() # 启动服务端,永远等着客户端来链接
urls.py
urls = [ ('/get_user',get_user), #第二个是函数,若是匹配成功,就去views.py中去找相应的函数去运行 ]
views.py
def get_user(env): d = {'name':'jason','pwd':'123','hobby':['read','running','music']} with open(r'get_user.html','r',encoding='utf-8') as f: data = f.read() temp = Template(data) #将data数据传给这个temp,作处理 res = temp.render(user=d) # 将字典d传递给前端页面 页面上经过变量名user就可以获取到该字典 return res
get_user.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> #jinja2模块,能够对字典 进行如下取值,同时这是jinja变量取值 {{ }}的语法 <p>{{ user }}</p> <p>{{ user.name }}</p> <p>{{ user['pwd'] }}</p> <p>{{ user.get('hobby') }}</p> </body> </html>
动静态页面
静态页面:就是一个写死的页面
动态页面:能够经过更改后端的数据,来反应到浏览器的页面上
eg:1.后端获取当前时间展现到前端
2.后端获取数据库中的数据展现到前端
客户端经过访问服务器获取当前时间
那么若是用户访问服务端,则客户端页面就会显示当前时间,这样该怎么作呢?
咱们要知道,页面就是要用到html,若是时间写在HTML,那么经过编码格式,他已经再也不是时间了,那么怎样将时间显示在页面呢?
作法:咱们要在wsgiref模块的基础上,先在html中写一串特定的字符,在后端将这串html和获取的时间做交换,具体看代码
wsgiref.py文件
from wsgiref.simple_server import make_server from urls import urls from views import * def run(env,response): """ :param env: 请求相关的全部数据 :param response: 响应相关的全部数据 :return: """ response('200 OK',[]) current_path = env.get('PATH_INFO') #env里面有 不少数据,咱们筛选有用的数据就行 # 先定义一个变量名 用来存储后续匹配到的函数名 func = None # for循环 匹配后缀 for url in urls: if current_path == url[0]: func = url[1] # 一旦匹配成功 就将匹配到的函数名赋值给func变量 break # 主动结束匹配 # 判断func是否有值 if func: res = func(env) else: res = error(env) return [res.encode('utf-8')] if __name__ == '__main__': server = make_server('127.0.0.1',8080,run) # 实时监听该地址 只要有客户端来链接 统一交给run函数去处理 server.serve_forever() # 启动服务端,永远等着客户端来链接
urls.py
from views import * urls = [ ('/get_time',get_time), #第二个是函数,若是匹配成功,就去views.py中去找相应的函数去运行 ]
views.py
from urls import * from datetime import datetime def get_time(): current_time = datetime.now().strftime('%Y-%m-%d %X') with open(r'get_time.html','r',encoding='utf-8') as f: #这是一串字符串 data= f.read() data = data.replace('$$time$$',current_time) return data
get_time.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> $$time$$ </body> </html>
客户端经过访问服务器获取数据库数据
获取数据库数据如今就和获取字典的方法差很少像了,只不过咱们须要建一个数据库,经过连接数据库,去数据库里面拿值
wsgiref.py文件
from wsgiref.simple_server import make_server from urls import urls from views import * def run(env,response): """ :param env: 请求相关的全部数据 :param response: 响应相关的全部数据 :return: """ response('200 OK',[]) current_path = env.get('PATH_INFO') #env里面有 不少数据,咱们筛选有用的数据就行 # 先定义一个变量名 用来存储后续匹配到的函数名 func = None # for循环 匹配后缀 for url in urls: if current_path == url[0]: func = url[1] # 一旦匹配成功 就将匹配到的函数名赋值给func变量 break # 主动结束匹配 # 判断func是否有值 if func: res = func(env) else: res = error(env) return [res.encode('utf-8')] if __name__ == '__main__': server = make_server('127.0.0.1',8080,run) # 实时监听该地址 只要有客户端来链接 统一交给run函数去处理 server.serve_forever() # 启动服务端,永远等着客户端来链接
urls.py
urls = [ ('/get_db',get_db), #第二个是函数,若是匹配成功,就去views.py中去找相应的函数去运行 ]
views.py
import pymysql def get_db(env): conn = pymysql.connect( host = '127.0.0.1', port = 3306, user = 'root', password = 'root', database = 'day56', charset = 'utf8', autocommit = True ) cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = "select * from userinfo" cursor.execute(sql) #提交sql语句,这个出发的是执行的对象并非一个值 res = cursor.fetchall() print(res) with open(r'get_db.html','r',encoding='utf-8') as f: data = f.read() temp = Template(data) ret = temp.render(user_list = res) # 将字典d传递给前端页面 页面上经过变量名user就可以获取到该字典 return ret
get_db.html
咱们这里用到了bootstrap搭建页面,这就是一个典型的动态页面
<!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.3.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h1 class="text-center">用户列表</h1> <table class="table table-bordered table-striped table-hover"> <thead> <tr> <th>id</th> <th>name</th> <th>pwd</th> </tr> </thead> <tbody> {% for user_dict in user_list %} <tr> <td>{{ user_dict.id }}</td> <td>{{ user_dict.name }}</td> <td>{{ user_dict.pwd }}</td> </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body> </html>
python三大主流web框架
A:socket部分 B:路由与视图函数对应关系 C:模板语法
Django | Flask | Tornado |
---|---|---|
大而全 自带的功能特别多 相似于航空母舰<br/> 有时候过于笨重 | 小而精 自带的功能特别少 相似于游骑兵<br/>第三方的模块特别多,若是将flask第三方模块所有加起来 彻底能够超过django<br/>比较依赖于第三方模块 | 异步非阻塞<br/> 牛逼到能够开发游戏服务器 |
A用的别人的 wsgiref<br/> B本身写的<br/> C本身写的 | A用的别人的 werkzeug(基于wsgiref)<br/> B本身写的<br/> C用的别人的 jinja2 | 三者全是本身写的 |