想学Django个小伙伴可以先看看这篇文章,过渡一下,方便理解框架~ 
Web框架,其实就是Web应用的建立;比如网页版的QQ,b站····都是Web应用软件;
Web应用又是什么?可以理解为基于浏览器的一些应用程序,用户只需要有浏览器即可,不需要再安装其他软件;
比如我们打开一个URL,Web服务器返回一个HTML页面给你,那么你在搜索或者URL拼接路径搜索的时候Web服务器是怎么知道要返回什么给你?下面介绍一下:
在介绍之前先介绍所需基础知识,同时也是Web运行所需的:
??[Web基础知识](Web入门 - HammerZe - 博客园 (cnblogs.com))
ps:b/s本质也是c/s架构
四大特性
数据格式
请求首行(http协议版本,网络请求的方法) 请求头(一大堆k,v键值对) /r/n # 换行符不能省略 请求体(存放的是一些数据,并不是每种请求方式都有请求体,get没有请求体,post有请求体) # 请求方式get:朝服务器索要数据,比如输入网址获得相应的数据post:向服务器提交数据,比如用户登录输入用户名和密码后,提交到后端做身份校验
响应格式、
响应首行(http协议版本,网络请求的方法) 响应头(一大堆k,v键值对) /r/n # 换行符不能省略 响应体(交给给浏览器展示给用户看的数据)
响应状态码
HTTP 状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型。响应分为五类:信息响应(100–199),成功响应(200–299),重定向(300–399),客户端错误(400–499)和服务器错误 (500–599)
| 分类 | 分类描述 |
|---|---|
| 1** | 信息,服务器收到请求,需要请求者继续执行操作 |
| 2** | 成功,操作被成功接收并处理 |
| 3** | 重定向,需要进一步的操作以完成请求 |
| 4** | 客户端错误,请求包含语法错误或无法完成请求 |
| 5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
# 注意公司还会自定义状态码 一般以10000开头参考:聚合数据请求方式
为了更方便的理解请求网页并返回数据的过程,写一套下面的程序帮助理解
import socketserver = socket.socket()server.bind(('127.0.0.1',8080))server.listen(5) # 池子while True: conn,addr = server.accept() data=conn.recv(1024) # print(data) # 忽略favicon.ico,拿到用户在url后面输入的字符串 data = data.decode('utf-8') conn.send(b'HTTP/1.1 200 Ok\r\n\r\n') # 获取字符串中特定的内容 正则和切割 current_path = data.split(' ')[1] # print(current_path) # /index if current_path =='/index': with open(r'E:\web组件\图书管理系统界面\图书管理系统.html','rb')as f: conn.send(f.read()) elif current_path == '/login': conn.send(b'hello') else: conn.send(b'Nothing to give you!') conn.close()

通过上面的例子,能够简单的理解通过get请求方式得到的页面是如何返回,但是我们个人手写得服务端存在问题,如果客户请求不同得页面那么我们就得写n多个if/else,数据得格式处理起来也比较繁琐······通过一个模块来解决这些问题wsgiref模块
# 解决了上述两个问题from wsgiref.simple_server import make_serverdef run(request,response): """ :param request:请求相关的所有数据 :param response:响应相关的所有数据 :return:返回给浏览器的数据 """ response('200 OK',[]) current_path = request.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) # 实时监听,一旦被访问会全部交给run函数处理 server.serve_forever() # 启动服务端封装的过程中主要解决:
网址的匹配问题
网址多匹配如何解决
功能复杂代码块如何解决,放在一个文件结构不清晰
'''服务端'''from wsgiref.simple_server import make_serverfrom views import *from urls import *'''urls.py 路由与视图函数的对应关系views.py主要存视图函数templates 文件夹主要存HTML文件拆分功能后只需在urls.py中书写对应关系,views.py中书写后端的业务逻辑即可'''def run(env, response): ''' :param env:请求相关的所有数据 :param response:响应相关的所有数据 :return:返回给浏览器的数据 ''' # print(env) # wsgiref 模块 将http格式的数据处理好 response('200 ok',[]) # 从env返回的大字典中拿出用户输入的内容 --->key current_path = env.get('PATH_INFO') # if current_path == '/index': # return [b'Hell index'] # elif current_path == 'login': # return [b'hello wsgiref'] # else: # return [b'404'] # 定义一个变量存储匹配到的函数名 func = None for url in urls: if current_path == url[0]: # 匹配成功将url对应的函数名赋值给func func = url[1] break # 结束当前循环 # 判断一下func是否有值 if func: res = func() else: res = error() return [res.encode('utf-8')]if __name__ == '__main__': server = make_server('127.0.0.1', 8081, run) # 实时监听,只要有客户端来了,就交给run函数执行 server.serve_forever() # 启动服务端'''urls.py 路由与视图函数的对应关系'''from views import *urls = [ ('/index',index), ('login',login)]'''views.py主要存视图函数下面统称为视图函数'''def index(env): return 'index'def login(env): return 'login'def error(env): return '404'# 返回文件def file(env): with open(r'E:\web组件\图书管理系统界面\图书管理系统.html','r',encoding='utf8')as f: return f.read()示例一:将时间同步到html页面
'''服务端'''from wsgiref.simple_server import make_serverfrom urls import *def run(env, response): ''' :param env:请求相关的所有数据 :param response:响应相关的所有数据 :return:返回给浏览器的数据 ''' # print(env) # wsgiref 模块 将http格式的数据处理好 response('200 ok', []) # 从env返回的大字典中拿出用户输入的内容 --->key current_path = env.get('PATH_INFO') # 定义一个变量存储匹配到的函数名 func = None for url in urls: if current_path == url[0]: # 匹配成功将url对应的函数名赋值给func func = url[1] 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', 8081, run) # 实时监听,只要有客户端来了,就交给run函数执行 server.serve_forever() # 启动服务端 '''urls.py'''from views import *urls = [ ('/get_time',get_time),]'''views.py'''# 同步时间def get_time(env): from datetime import datetime current_time = datetime.now().strftime('%Y-%m-%d %X') with open(r'get_time.html','r',encoding='utf8') as f: data = f.read() data = data.replace('AAA',current_time) # 用替换的方式将数据传到HTML文件中 return data<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <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></head><style> #d1{ font-size: 48px; color: tomato; }</style><body><div > <div > <div id="d1" > AAA </div> </div></div></body></html>该模块是flask框架必备的模块,在这里只使用jinjia2模块来写我们的模板语法
需求:将后端字典展示到HTML页面上
'''服务端和上面一样''''''urls.py'''from views import *urls = [ ('/get_dict',get_dict) ]'''views.py'''# 获取字典def get_dict(env): user_dict = {'id': 1, 'name': 'Hammer', 'hobby': 'python'} from jinja2 import Template with open(r'templates/get_dict.html', 'r', encoding='utf8') as f1: data = f1.read() temp = Template(data) res = temp.render(user_data=user_dict) # 将user_dict传递给html页面,在该页面使用user_data调用 return res<!--由于导入了jinjia2模块,这里可以直接使用模板语法,类似python的字典方法--><body>{{user_data}}{{user_data.id}}{{user_data['name']}}{{user_data.get('hobby')}}</body>需求:操作MySQL数据并且展示到HTML页面上
注意:数据是在后端处理完之后发送到前端的
'''服务端'''from wsgiref.simple_server import make_serverfrom urls import *def run(env, response): ''' :param env:请求相关的所有数据 :param response:响应相关的所有数据 :return:返回给浏览器的数据 ''' # print(env) # wsgiref 模块 将http格式的数据处理好 response('200 ok', []) # 从env返回的大字典中拿出用户输入的内容 --->key current_path = env.get('PATH_INFO') # 定义一个变量存储匹配到的函数名 func = None for url in urls: if current_path == url[0]: # 匹配成功将url对应的函数名赋值给func func = url[1] 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', 8081, run) # 实时监听,只要有客户端来了,就交给run函数执行 server.serve_forever() # 启动服务端'''路由'''from views import *urls = [ ('/get_db',get_db)]'''视图函数'''# 获取数据库的内容def get_db(env): import pymysql conn = pymysql.connect( user='root', password='7410', port=3306, host='127.0.0.1', database='info', charset='utf8', autocommit=True ) cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) sql = 'select * from emp;' rows = cursor.execute(sql) res = cursor.fetchall() # [{},{},{}] # print(res) with open(r'templates/get_db.html','r',encoding='utf8') as f: data = f.read() temp = Template(data) total_res = temp.render(data_list = res) return total_res<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title> <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></head><body><div > <div > <h1 >用户数据</h1> <div > <table > <thead> <tr > <td>id</td> <td>name</td> <td>sex</td> <td>age</td> <td>dep_id</td> </tr> </thead> <tbody> {%for user_dict in data_list%} <tr > <td>{{user_dict.id}}</td> <td>{{user_dict.name}}</td> <td>{{user_dict.sex}}</td> <td>{{user_dict.age}}</td> <td>{{user_dict.dep_id}}</td> </tr> {%endfor%} </tbody> </table> </div> </div></div></body></html>
到此前后端和数据库交互就都完成了,这所有的功能都可以用Django完成,上面只是一个推导过程~

{{}}{%%}