AI智能
改变未来

[在学习Django框架之前所需要了解的知识点]


[在学习Django框架之前所需要了解的知识点]

Web框架本质

我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端。 这样我们就可以自己实现Web框架了

用户的浏览器一输入网址,会给服务端发送数据,那浏览器会发送什么数据?怎么发?这个谁来定? 你这个网站是这个规定,他那个网站按照他那个规定,这互联网还能玩么?

所以,必须有一个统一的规则,让大家发送消息、接收消息的时候有个格式依据,不能随便写。

这个规则就是HTTP协议,以后浏览器发送请求信息也好,服务器回复响应信息也罢,都要按照这个规则来。

HTTP协议主要规定了客户端和服务器之间的通信格式,那HTTP协议是怎么规定消息格式的呢?

让我们首先打印下我们在服务端接收到的消息是什么。

我们发现收发的消息需要按照一定的格式来,这里就需要了解一下HTTP协议了。

网络协议:

HTTP协议---------------数据传输是明文HTTPS协议-------------数据传输是密文websocket协议---------数据传输是密文

HTTP协议

超文本传输协议:规定了浏览器与服务端之间数据交互的格式

1. HTTP协议的四大特性

1.基于TCP、IP协议作用于应用层之上的协议2.基于请求响应  -- 浏览器给服务端发起请求,服务端收到后做出回应3.无状态  -- 不保存用户端的登录状态,见你千百遍我都当你如初见  ps:cookie、session、token...4.无(短)连接  -- 一次请求响应后即断开连接          ps:长连接:websocket

2. HTTP协议的数据传输格式

请求数据格式:请求首行(请求方法...)请求头(一大堆K:V键值对)\\r\\n  ---换行请求体(并不是所有的请求方法都有  主要用来携带敏感性数据)响应数据格式:响应首行(响应状态码...)响应头(一大堆K:V键值对)\\r\\n  ---换行响应体(展示给用户的数据)

3. 响应状态码

用简单的数字来表示一串中文意思1XX:服务端已经接受到你的数据正在处理,你可以继续提交2XX:200 OK >>>:请求成功3XX:重定向 --原本想访问A,但是内部跳到B4XX:403当前请求不符合条件 404请求资源不存在5XX:服务器内部错误ps:除了上述统一的响应状态码之外,公司还可以自定义自己的状态码

请求方法:

1.get请求朝别人索要数据2.post请求朝别人提交数据>>>上述两种请求都可以携带额外的参数<<<get请求携带数据的方式:url?username=jason&hobby=mnpost请求携带数据的方式:      数据是放在请求体里面的

请求数据格式示例:

# 请求首行--\\r\\n是换行符b\'GET / HTTP/1.1\\r\\n# 请求头(都是一大堆K:V键值对)Host: 127.0.0.1:8080\\r\\nConnection: keep-alive\\r\\nsec-ch-ua: "Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"\\r\\nsec-ch-ua-mobile: ?0\\r\\nUpgrade-Insecure-Requests: 1\\r\\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36\\r\\nAccept: 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\\r\\nSec-Fetch-Site: none\\r\\nSec-Fetch-Mode: navigate\\r\\nSec-Fetch-User: ?1\\r\\nSec-Fetch-Dest: document\\r\\nAccept-Encoding: gzip, deflate, br\\r\\nAccept-Language: zh-CN,zh;q=0.9\\r\\n\\r\\n# 请求体 (下面是空的:因为发出的是get请求,get请求不需要请求体)\'

纯手写web框架(无需掌握,了解即可)

类型转换小常识
# 采用此类方式实现类型转换可以不需要用encode 和 decode# 只需要认识str和bytes就行了data = b\'hello world\'# 转字符串data1 = str(data,encoding=\'utf8\')print(data1)# 转bytes类型data2 = bytes(data1,encoding=\'utf8\')print(data2)类型转换小常识
import socketserver = socket.socket()  # 默认就是TCP协议server.bind((\'127.0.0.1\',8080))server.listen(5)while True:conn, addr = server.accept()  # 三次四次挥手data = conn.recv(1024)res = data.decode(\'utf8\')conn.send(b\'HTTP/1.1 200 OK\\r\\n\\r\\n\')# 字符串切割获取地址path = res.split(\' \')[1]# 判断地址if path == \'/index\':# conn.send(b\'index\')with open(r\'fh.html\',\'rb\') as f:data = f.read()conn.send(data)elif path == \'/login\':conn.send(b\'login\')conn.close()纯手撸web框架## fh.html<!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><h1 class="text-center">这是一个非常牛逼的页面</h1></body></html>fh.html

问题:

  — 服务端代码重复

  — 手动处理http数据格式过于繁琐

基于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()  # 启动服务端

问题

  — 网址很多的情况下如何匹配

  — 网址多匹配如何解决

  — 功能复杂代码块如何解决

封装处理

1.定义一个网址与功能函数的对应关系# 地址与功能的对应关系urls = [(\'/index\',index_func),(\'/login\',login_func),(\'/reg\',reg_func),]2.按照功能的不同划分成不同的py文件urls.py views.py 服务端.py3.书写服务端代码func = None# for循环判断for url_tuple in urls:  # (),()if current_path == url_tuple[0]:# 将匹配到的函数名赋值给func变量func = url_tuple[1]break# 判断func是否有值if func:# 执行对应的函数res = func(request)else:res = errors(request)return [bytes(res,encoding=\'utf8\')]

动静态网页

静态网页:  页面上的数据全部都是写死的,万年不变动态网页:  页面上的数据来源于后端(代码、数据库)

1.访问网址展示当前时间(由后端模块生成并展示到html页面)

def get_time_func(request):from datetime import datetimecurrent_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(\'sadadadad\',current_time)return data

2.后端有一个字典,将该字段传递给html页面,并且在该页面上还可以使用字典取值的各种操作 python强大而优秀的三方库为我们解决了这个问题 实现模板渲染 模板语法的第三方模块:jinja2模块  安装方式:pip3 install jinja2ps:该模块是flask框架必备的模块 所以下载flask也会自动下载该模块

def get_dict_func(request):user_dict = {"username":\'jason\',\'password\':123,\'hobby\':\'study\'}from jinja2 import Templatewith open(r\'templates/get_dict.html\',\'r\',encoding=\'utf8\') as f:data = f.read()  # 字符串temp = Template(data)# 将user_dict传递给get_dict.html页面 在该页面上使用变量名user_data调用res = temp.render(user_data=user_dict)return res

模板语法(用近似于python的语法在html文件上操作数据) 红色标记为固定语法,jinja2支持字典、列表等数据类型,在前端页面文件中的使用方式也和python中如出一辙。

{{user_data}}{{user_data[\'username\']}}{{user_data.get(\'password\')}}{{user_data.hobby}}{%for user_dict in data_list%}<tr><td>{{user_dict.id}}</td><td>{{user_dict.name}}</td><td>{{user_dict.age}}</td></tr>{%endfor%}

3.获取MySQL数据库数据展示到页面上

def get_db_func(request):import pymysqlconn = pymysql.connect(host=\'127.0.0.1\',port=3306,user=\'root\',password=\'123\',db=\'db666\',charset=\'utf8\',autocommit=True)cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)sql = \'select * from userinfo\'affect_rows = cursor.execute(sql)res1 = cursor.fetchall()  # [{},{},{}]with open(r\'templates/get_db.html\',\'r\',encoding=\'utf8\') as f:data = f.read()  # 字符串temp = Template(data)# 将user_dict传递给get_dict.html页面 在该页面上使用变量名user_data调用res = temp.render(data_list=res1)return res

总结

1.纯手撸web框架

  • 1.socket代码需要我们自己写
  • 2.http格式的数据自己处理(只能拿到用户输入的路由)

2.基于wsgiref模块

  • 1.封装了socket代码
  • 2.处理了http数据格式

  web服务网关接口

  • 1.请求来的时候解析http格式的数据,封装成了大字典
  • 2.响应走的时候把数据打包成符合http格式,在返回给浏览器

3.根据功能的不同拆分成不同的文件夹

  urls.py 路由与视图函数对应关系:主要是匹配浏览器请求的视图页面并交由对应视图函数处理

  views.py 视图函数:得到浏览器的页面请求及浏览器携带的请求数据,进行html页面提取、数据处理、模板渲染并返回

  templates 模板文件夹:放有所有前端html页面文件夹

  • 1.第一步添加路由与视图函数的对应关系
  • 2.去views中书写功能代码
  • 3.如果需要使用到html则去模板文件夹中操作

4.jinja2模板语法

  {{···}}  {%···%}

5.简易版本web框架流程图  

Python三大主流web框架

1.django框架:特点:大而全,自带的功能组件非常非常非常的多!类似于航空母舰不足之处: 有时候过于笨重

2.flask框架:特点:小而精,自身的功能组件非常非常非常的少!类似于游骑兵

但是第三方模块非常之多,如果把第三方模块全部叠加起来完全可以盖过django并且也越来越像django不足之处: 比较依赖于第三方的开发者,有时候也会受限于第三方模块

  ps:三行代码就可以启动一个flask后端服务

3.tornado框架:特点:异步非阻塞,支持高并发

速度非常的快 快到可以开发游戏服务器  ps:Sanic、FastAPI…

A : socket部分 B: 路由与视图匹配 C: 模版语法
django 别人的, wsgiref模块 自己写的
flask 别人的,wsgiref模块封装之后werkzeug 自己写的
tornado 自己写的 自己写的
赞(0) 打赏
未经允许不得转载:爱站程序员基地 » [在学习Django框架之前所需要了解的知识点]