django

引言

  • 所有的web应用本质上就是一个socket服务端,而用户的浏览器。

  • 软件开发架构

cs架构
bs架构
本质上,bs架构也是cs架构
  • http协议
网络协议
http协议 数据传输是明文的
https协议 数据传输是密文的
websocket协议 数据传输是密文的 四大特性:
1.基于请求响应
2.基于TCP,IP作用于应用层之上的协议
3.无状态
4.短/无链接 数据格式(请求格式)
请求首行
请求头 请求体 响应状态码
1xx
2xx 200
3xx 301 302
4xx 403 404
5xx 500

原始自定义web框架

# 你可以将web框架理解成服务端
import socket server = socket.socket()
server.bind(("127.0.0.1",8080))
server.listen(5) while True:
conn,addr = server.accept()
data = conn.recv(1024)
print(data)
data = data.decode("utf-8")
conn.send(b"hello web")
conn.close()
  • web服务的本质就是在上述代码的基础上扩展出来的

  • 在网页上直接输入ip+port(127.0.0.1:8080)得到的结果是127.0.0.1 发送的响应无效。原因是写的服务端向客户端发送的数据格式不符合HTTP协议。

  • 但是在服务器上可以收到网页的请求如下:

b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8080\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,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'

b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8080\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\nSec-Fetch-Site: cross-site\r\nSec-Fetch-Mode: navigate\r\nSec-Fetch-Dest: document\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n'
  • 想让客户端(浏览器)收到服务端发送的数据,需要遵循HTTP协议,因此在给客户端回复消息的时候必须按照HTTP协议规则加上响应状态行

低配版自定义web框架--遵循HTTP协议

# 你可以将web框架理解成服务端
import socket server = socket.socket()
server.bind(("127.0.0.1",8080))
server.listen(5) while True:
conn,addr = server.accept()
data = conn.recv(1024)
print(data)
data = data.decode("utf-8")
conn.send(b"HTTP/1.1 200 OK\r\n\r\n")
conn.send(b"hello web")
conn.close()

中配版自定义web框架---根据不同的url返回不同的内容

  • 低配版 ----if判断

原理:将浏览器发送到服务端的数据进行处理,然后做一个判断即可

b'GET /index HTTP/1.1\r\n
Host: 127.0.0.1:8080\r\n
Connection: keep-alive\r\n
Cache-Control: max-age=0\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\n
Sec-Fetch-Site: cross-site\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'
# 你可以将web框架理解成服务端
import socket server = socket.socket()
server.bind(("127.0.0.1",8080))
server.listen(5) while True:
conn,addr = server.accept()
data = conn.recv(1024)
current_path = data.decode("utf-8").split(" ")[1]
conn.send(b"HTTP/1.1 200 OK\r\n\r\n")
if current_path =="/index":
conn.send(b"hello index")
elif current_path =="/login":
conn.send(b"hello login")
else:
conn.send(b"404 error")
conn.close()
  • 中配版---使用函数与列表结合

    低配版的问题:虽然解决了不同url路径返回不同内容的需求,但是如果有很多路径要判断怎么办?难道挨个写if判断?

# 你可以将web框架理解成服务端

def index():
return "hello index" def login():
return "hello login" def error():
return "404 error" urls = [
("/login",login),
("/index",index),
] import socket server = socket.socket()
server.bind(("127.0.0.1",8080))
server.listen(5) while True:
conn,addr = server.accept()
data = conn.recv(1024)
current_path = data.decode("utf-8").split(" ")[1]
conn.send(b"HTTP/1.1 200 OK\r\n\r\n")
func = None
for url in urls:
if current_path ==url[0]:
func = url[1]
break
if func:
ret = func()
else:
ret = error()
conn.send(ret.encode("utf-8"))
conn.close()
上面的代码的不足之处
1.代码重复(服务端代码所有人都要重复写)
2.手动处理http格式的数据 并且只能拿到url后缀 其他数据获取繁琐(数据格式一样处理的代码其实也大致一样 重复写)
3.并发的问题

基于wsgiref模块

from wsgiref.simple_server import make_server

def index(env):
return 'index' def login(env):
return "login" def error(env):
return '404 error' # url与函数的对应关系
urls = [
('/index',index),
('/login',login),
] def run(env,response):
'''
:param env: 请求相关的所有数据
:param response: 响应相关的所有数据
:return: 返回浏览器的数据
'''
# print(env) #大字典 wsgiref模块帮你处理好http格式的数据 封装成了字典让你更加方便的操作
# 从env中取
response("200 OK",[]) # 响应首行 响应头
current_path = env.get("PATH_INFO")
# 定义一个变量 存储匹配到的函数名
func = None
for url in urls:
if current_path == url[0]:
# 将url对应得函数名赋值给func
func = url[1]
break # 匹配到一个之后 应该立刻结束for循环
# 判断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)
"""
会实时监听127.0.0.1:8080地址 只要有客户端来了
都会交给run函数处理(加括号触发run函数的运行) fladk启动源码
make_server("127.0.0.1",8080,obj)
__call__
"""
server.serve_forever() # 启动服务端

代码拆分及主要文件说明

urls.py文件
from views import * # url与函数的对应关系
urls = [
('/index',index),
('/login',login),
]
views.py文件
def index(env):
return 'index' def login(env):
return "login" def error(env):
return '404 error'
基于wsgiref模块
from wsgiref.simple_server import make_server
from urls import urls
from views import * def run(env, response):
response('200 OK', []) # 响应首行 响应头
current_path = env.get('PATH_INFO')
func = None
for url in urls: # url (),()
if current_path == url[0]:
# 将url对应的函数名赋值给func
func = url[1]
break # 匹配到一个之后 应该立刻结束for循环
# 判断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)
server.serve_forever() # 启动服务端 文件说明:
urls.py 路由与视图函数对应关系
view.py 视图函数(后端业务逻辑)
templates文件夹 专门用于存储html文件 按照功能的不同拆分之后 后续添加功能只需要在urls.py书写对应关系 然后去views.py书写业务逻辑即可

返回html文件

urls.py文件
from views import * # url与函数的对应关系
urls = [
('/index',index),
('/login',login),
("/html",html)
]
views.py文件
def index(env):
return 'index' def login(env):
return "login" def html(env):
with open("html.html","r",encoding = "utf-8") as f:
data = f.read()
return data def error(env):
return '404 error'
基于wsgiref模块
from wsgiref.simple_server import make_server
from urls import urls
from views import * def run(env, response):
response('200 OK', []) # 响应首行 响应头
current_path = env.get('PATH_INFO')
func = None
for url in urls: # url (),()
if current_path == url[0]:
# 将url对应的函数名赋值给func
func = url[1]
break # 匹配到一个之后 应该立刻结束for循环
# 判断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)
server.serve_forever() # 启动服务端
  • 动静态网页
静态网页
页面上的数据是直接写死的 万年不变
动态网页
数据是实时获取的
eg:
1.后端获取当前时间展示到html页面上
2.数据是从数据库中获取的展示到html页面上 动态网页制作:后端获取当前时间展示到html页面上
import datetime
def get_time(env):
current_time = datetime.datetime.now().strftime("%Y-%m-%d %X")
#如何将后端获取的数据传递给前端html文件
with open("mytime.html","r",encoding="utf-8") as f:
data = f.read()
# data 就是一堆字符串
data = data.replace("wdefewfew",current_time) # 在后端将html页面处理好之后再返回给前端
return data
  • 模版语法

    • 原理:

      • 模版的原理就是字符串替换,只要在HTML页面中遵循jinja2的语法规则书写,内部就会按照指定的语法进行替换
    • 模版语法案例一

#注意要将该函数与路由对应关系加入到urls.py
from jinja2 import Template def get_dict(env):
user_dict ={"username":"jason","age":18,"hobby":"read"}
with open(r"templates/04 get_dict.html","r",encoding=
"utf-8") as f:
data = f.read()
tmp = Template(data)
res = tmp.render(user_dic)
#给get_dict.html传递一个值 页面上通过变量名user就能够拿到user_dict,变量名是随意的,不过要见名知意
return res #get_dict
<body>
{{xx}} //获取字典 //获取字典中的值的三种方式
{{xxx.get("username")}}
{{xxx["password"]}}
{{xxx.hobbies}}
</body>
  • 模版语法案例二----后端数据库中数据展示到前端页面
def get_mysql(env):
conn = pymysql.connect(
host = "127.0.0.1",
port = 3306,
user = "root",
password = "123",
database = "user",
charset = "utf8"
autocommit = True
)
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
sql = "select * from info;"
rows = cursor.execute(sql)
data_list = cursor.fetchall()
with open(r"template/get_mysql.html","r",encoding="urf-8") as f:
data = f.read()
temp = Template(data)
res = temp.render(data_list=data_list)
return res
自定义简易版本web框架流程图

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

web框架推导的更多相关文章

  1. 自定义web框架(django)

    Django基础了解知识 HTTP协议(超文本传输协议) HTTP协议 四大特性: 基于TCP/IP之上作用于应用层 基于请求响应 无状态 引申出cookie session token-- 无连接 ...

  2. Web开发框架推导

    本文欲回答这样一个问题:在 「特定环境 」下,如何规划Web开发框架,使其能满足 「期望 」? 假设我们的「特定环境 」如下: 技术层面 使用Java语言进行开发 通过Maven构建 基于Spring ...

  3. Django-手撸简易web框架-实现动态网页-wsgiref初识-jinja2初识-python主流web框架对比-00

    目录 自己动手实现一个简易版本的web框架 手撸一个web服务端 根据请求 url 做不同的响应处理 基于wsgiref模块实现服务端 用wsgiref 模块的做的两件事 拆分服务端代码 支持新的请求 ...

  4. 自创Web框架之过度Django框架

    目录 自创Web框架之过度Django框架 软件开发架构 HTTP协议 Web框架之"撸起袖子加油干" Web框架之通过wsgiref加油干 封装优化处理 动静网页 jinjia2 ...

  5. Python(九)Tornado web 框架

    一.简介 Tornado 是 FriendFeed 使用的可扩展的非阻塞式 web 服务器及其相关工具的开源版本.这个 Web 框架看起来有些像web.py 或者 Google 的 webapp,不过 ...

  6. 转-基于NodeJS的14款Web框架

    基于NodeJS的14款Web框架 2014-10-16 23:28 作者: NodeJSNet 来源: 本站 浏览: 1,399 次阅读 我要评论暂无评论 字号: 大 中 小 摘要: 在几年的时间里 ...

  7. 初步认识Node 之Web框架

    上一篇我们认识了Node是什么之后,这一篇我们主要了解的就是它的框架了.而它的框架又分为两大类,Web框架和全栈框架,接下来我们一个一个的来了解.    Web框架 Web框架可以细分为Web应用程序 ...

  8. 【原】Go语言及Web框架Beego环境无脑搭建

    本文涉及软件均以截至到2013年10月12日的最新版本为准 1. 相关软件准备: 1) go1.2rc1.windows-386.msi,对应32位windows系统安装使用 下载地址: https: ...

  9. 【译】什么是 web 框架?

    Web 应用框架,或者简单的说是“Web 框架”,其实是建立 web 应用的一种方式.从简单的博客系统到复杂的富 AJAX 应用,web 上每个页面都是通过写代码来生成的.我发现很多人都热衷于学习 w ...

随机推荐

  1. 在Mac上打开多个Unity实例

    alias koa_unity="open -n /Applications/Unity\ 5.2.2/Unity.app" alias rob_unity="open ...

  2. Spine学习四 - 在动作上绑定回调事件

    Spine事件特性: SpineEvent(string startsWith = "", string dataField = "", bool includ ...

  3. 游戏UI系统设计

    1.需要实现的功能 UI界面的管理(窗体加载.窗体显示.窗体隐藏.窗体销毁等) UI分层次(比如弹窗.广播信息需要在上层) UI界面的出场.入场动画 UI界面的显示效果(比如带透明背景.带高斯模糊背景 ...

  4. Azure Storage 系列(二) .NET Core Web 项目中操作 Blob 存储

    一,引言 上一篇文章,我们介绍到在实际项目中系统会产生大量的日志文件,用户上传的头像等等,同时也介绍到可以使用Azure Blob Storage 来存储项目中的一些日志文件,用户头像,用户视频等等. ...

  5. Python 利用三个简易模块熟悉前后端交互流程

    准备工作 在学习Django之前,先动手撸一个简单的WEB框架来熟悉一下前后端交互的整体流程 本次用到的模块: 1.wsgiref,这是一个Python自带的模块,用于构建路由与视图 2.pymysq ...

  6. ThreadLocal是什么?谈谈你对他的理解

    1.ThreadLocal是什么 从名字我们就可以看到ThreadLocal叫做线程变量,意思是ThreadLocal中填充的变量属于当前线程,该变量对其他线程而言是隔离的.ThreadLocal为变 ...

  7. leetcode刷题-59螺旋矩阵2

    题目 给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵. 思路 与螺旋矩阵题完全一致 实现 class Solution: def generateM ...

  8. Struts 2 漏洞专题 | S2-008

    漏洞简介 为了防止攻击者在参数内调用任意方法,默认情况下将标志xwork.MethodAccessor.denyMethodExecution设置为true,并将SecurityMemberAcces ...

  9. python应用 曲线拟合 02

    前情提要 CsI 闪烁体晶体+PD+前放输出信号满足: $U(t) = \frac{N_f\tau_p}{\tau_p-\tau_f} \left[ e^{-\frac{t}{\tau_p}}-e^{ ...

  10. mobiscroll

    https://docs.mobiscroll.com/3-2-3/jquery/calendar#!options