[在学习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. maven-plugin-shade 详解

    一.介绍 [1] This plugin provides the capability to package the artifact in an uber-jar, including its d ...

  2. Python数据分析入门(十):数据清洗和准备

    数据清洗是数据分析关键的一步,直接影响之后的处理工作 数据需要修改吗?有什么需要修改的吗?数据应该怎么调整才能适用于接下来的分析和挖掘? 是一个迭代的过程,实际项目中可能需要不止一次地执行这些清洗操作 ...

  3. [GDKOI2021] 普及组 Day2 总结

    [ G D K O I 2021 ] 普 及 组 D a y 2 总 结 [GDKOI2021] 普及组 Day2 总结 [GDKOI2021]普及组Day2总结 时间安排和昨天的GDKOI2021 ...

  4. VisualGDB_VS2010_开发PHP扩展

    1.新建一个Linux项目

  5. Linux 用户和用户组管理(useradd userdel groupadd groupdel)

    Linux 用户和用户组管理 Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统. Linux系统用户账户的 ...

  6. S-Trees UVA - 712

      A Strange Tree (S-tree) over the variable set Xn = {x1,x2,...,xn} is a binary tree representing a ...

  7. Day11_49_HashTable

    HashTable * HashTable是较早期的使用Hash算法的一种容器结构,现在基本已被淘汰,单线程多使用HashMap,多线程使用ConcurrentHashMap. * HashTable ...

  8. 实现服务端和客户端的实时双向数据传输-WebSocket简单了解

    WebSocket 前段时间项目中遇到了消息推送的问题,当时采用客户端轮询,每隔 5s 请求一次数据.由于轮询的效率低,非常浪费资源.后面准备把轮询调整为使用 WebSocket 来建立连接,实现推送 ...

  9. 微服务的进程间通信(IPC)

    微服务的进程间通信(IPC) 目录 微服务的进程间通信(IPC) 术语 概述 通信视角 APIs 消息格式 RPC REST gRPC 断路器 API通信的健壮性 服务发现 异步消息 概念 消息 消息 ...

  10. MySQL 储存引擎知识点

    一:MySQL 存储引擎概述 1.1 什么是存储引擎: '''MySQL中的数据用各种不同的技术存储在文件(或者内存)中.这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平并且最终提供广泛 ...