[在学习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,但是内部跳到B
4XX:403当前请求不符合条件 404请求资源不存在
5XX:服务器内部错误
ps:除了上述统一的响应状态码之外,公司还可以自定义自己的状态码

请求方法:

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

请求数据格式示例:

# 请求首行--\r\n是换行符
b'GET / HTTP/1.1\r\n
# 请求头(都是一大堆K:V键值对)
Host: 127.0.0.1:8080\r\n
Connection: keep-alive\r\n
sec-ch-ua: "Google Chrome";v="89", "Chromium";v="89", ";Not A Brand";v="99"\r\n
sec-ch-ua-mobile: ?0\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36\r\n
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\r\n
Sec-Fetch-Site: none\r\n
Sec-Fetch-Mode: navigate\r\n
Sec-Fetch-User: ?1\r\n
Sec-Fetch-Dest: document\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-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 socket

server = 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_server

def 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 服务端.py
3.书写服务端代码
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 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('sadadadad',current_time)
return data

2.后端有一个字典,将该字段传递给html页面,并且在该页面上还可以使用字典取值的各种操作

 python强大而优秀的三方库为我们解决了这个问题

 实现模板渲染 模板语法的第三方模块:jinja2模块

  安装方式:pip3 install jinja2

ps:该模块是flask框架必备的模块 所以下载flask也会自动下载该模块

def get_dict_func(request):
user_dict = {"username":'jason','password':123,'hobby':'study'}
from jinja2 import Template
with 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 pymysql
conn = 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 自己写的 自己写的

[在学习Django框架之前所需要了解的知识点]的更多相关文章

  1. python3 Django框架报错(备忘录)

    这篇博客主要总结的学习Django框架中,遇到的报错如何去解决问题: 1.decimal.InvalidOperation: decimal.InvalidOperation: [<class ...

  2. wsgiref模块、web框架、django框架简介

    """web框架:将前端.数据库整合到一起的基于互联网传输的python代码 web框架也可以简单的理解为是软件开发架构里面的'服务端'""" ...

  3. django框架1

    简介 1.前端    与用户打交道的界面 2.web框架    可以将前端和数据库整合到一起 3.数据库    专门用于存储数据 内容概要 纯手撸web框架 基于wsgiref模块 优化措施 动静态网 ...

  4. TypeScript基本知识(为学习AngularJS2框架做个小铺垫)

    学习angularjs2框架,需要了解一些TypeScript知识点,基本了解下面这几个知识点学习AngularJS2 就够用了 1.TypeScript 1.1显示类型的定义 TypeScript类 ...

  5. 开始学习Django,配置静态登录页面

    开始学习Django,配置静态登录页面 准备阶段 众所周知,Django是一个重量级的设备齐全的web开发框架.在学习Django前我们需要具备如下的知识点: python基础编程 并发 网络编程 H ...

  6. Django框架学习

    两个月前学习的Django框架,写了个简易婚恋调查网站,代码就懒得全贴了,有两张图记录下

  7. Django学习(二) Django框架简单搭建

    为了快速学习Python进行Web的开发,所以我不准备从Python的基础学起,直接从Django框架入手,边学框架边学Python的基础知识. 下面就开始Django的快速开发之旅吧. 关于Djan ...

  8. WEB框架-Django框架学习-预备知识

    今日份整理,终于开始整个阶段学习的后期了,今日开始学习Django的框架,加油,你是最胖的! 1.web基础知识 1.1 web应用 Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是 ...

  9. Python学习笔记_04:Django框架简介

    目录 1 什么是Django? 2 Django框架的开发环境搭建 3 Django操作MySql数据库简介 4 功能强大的Django管理工具应用 1 什么是Django? Django是应用于We ...

随机推荐

  1. 8、Spring教程之静态代理/动态代理

    为什么要学习代理模式,因为AOP的底层机制就是动态代理! 代理模式: 静态代理 动态代理 学习aop之前 , 我们要先了解一下代理模式! 静态代理 静态代理角色分析 抽象角色 : 一般使用接口或者抽象 ...

  2. 图解 | 原来这就是 IO 多路复用

    为了讲多路复用,当然还是要跟风,采用鞭尸的思路,先讲讲传统的网络 IO 的弊端,用拉踩的方式捧起多路复用 IO 的优势. 为了方便理解,以下所有代码都是伪代码,知道其表达的意思即可. Let's go ...

  3. java例题_16 九九乘法表

    1 /*题目:输出 9*9 口诀. 2 程序分析:分行与列考虑,共 9 行 9 列,i 控制行,j 控制列. 3 */ 4 5 /*分析 6 * 用两侧for循环,外层循环还要控制换行 7 * 换行时 ...

  4. 有了CMDB,为什么还需要应用配置管理?

    有了CMDB,为什么还需要应用配置管理? 你不妨先停下来,思考一下这个问题. 我抛出的观点是: CMDB是面向资源的管理,应用配置是面向应用的管理. 请注意,这里是面向"资源",不 ...

  5. Linux 服务器性能测试报告-sysbench命令实践

    Linux 服务器性能测试报告 我们使用linux 工具sysbench 来测试linux服务器性能,目前在Centos上进行操作 Install sysbench yum -y install sy ...

  6. 一文带大家彻底搞懂Hystrix!

    前言? Netflix Hystrix断路器是什么? Netflix Hystrix是SOA/微服务架构中提供服务隔离.熔断.降级机制的工具/框架.Netflix Hystrix是断路器的一种实现,用 ...

  7. jq分页功能。

    最近在写官网的分页功能.在网上找了很多案例都太复杂也太重.所以准备写一个简单一点的分页. 需求:把请求到的数据做分页. 准备:使用了网上一个简单的分页插件. 思路:分页相当于tab切换功能.具体实操把 ...

  8. 【Python学习笔记】-虚拟环境virtualenv

    在开发python应用程序的时候,系统安装的python3只有一个版本:3.4.所有的第三方的包都回被pip安装到python3的site-packages目录下. 如果我们要要同时开发多个应用程序, ...

  9. 201871030139-于泽浩 实验二 个人项目D{0-1} KP

    201871030139-于泽浩 实验二 个人项目D{0-1} KP 项目 内容 课程班级博客连接 2018级卓越班 这个作业要求连接 软件工程个人项目 我的课程学习目标 (1)掌握软件项目个人开发流 ...

  10. ES6转ES5(Babel转码器)

    ES6转ES5(Babel转码器) 前提:必须在VScode中已经安装了Node.js 官网:https://nodejs.org/en/ 一.安装命令行转码工具 npm install --glob ...