一、web框架

  框架即framework,特指为一个开放性问题而设计的具有一定约束性的支撑结构。使用框架可以快速的开发特定的系统。

浏览器与server交互的列子:

浏览器作为客户端,server.py作为server服务端。

  1. 浏览器通过url向服务端发送请求
  2. 服务端接受到请求后就可以给客户端发送数据
  3. 发送的数据可以被浏览器渲染成一个页面

其实所有的web框架都是在这个的前提下做的一步一步的封装。这就是第一步!什么功能都没有,仅仅完成连接和最简单地数据发送:

# 导入socket模块
import socket
# 拿到浏览器发送的信息并处理浏览器即客户端发送的请求并返回数据
def handle_request(client):
buf = client.recv(1024)
client.send("HTTP/1.1 200 ok \r\n\r\n".encode('utf8')) client.send("<h1 style='color:red'>Hello zhangrenguo</h1>".encode('utf8'))
# 建立socket对象连接绑定IP和端口
def main():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 8001))
server.listen(5) # 接受客户端的socket请求,并给客户发送信息
while True:
coon, addr = server.accept()
handle_request(coon)
coon.close() # 执行main函数
if __name__ == '__main__':
main()

二、web应用

  对于所有的web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。

上面就已经简单的实现了一个web项目,但是进一步处理的话返回的应该是个html文件:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<h1 style='color:red'>Hello zhangrenguo</h1>
</body>
</html>

index.html

# 导入socket模块
import socket # 处理浏览器即客户端发送的请求并返回数据
def handle_request(client):
buf = client.recv(1024)
client.send("HTTP/1.1 200 ok \r\n\r\n".encode('utf8'))
with open('index.html', 'rb')as f:
data = f.read()
client.send(data) # 建立socket对象连接绑定
def main():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 8001))
server.listen(5) # 接受客户端的socket请求,并给客户发送信息
while True:
coon, addr = server.accept()
handle_request(coon)
coon.close() if __name__ == '__main__':
main()

server.py

web应用的流程:

1、浏览器发送一个http请求
2、服务器收到请求,并生成一个HTML文件
3、服务器把HTML文件d作为http响应的body发送给浏览器
4、浏览器收到http响应,从HTTP body取出HTML文档并显示

三、web服务器

  wsgi:web server gateway interface

以上已经建立了一个最简单的web框架了,但是我们还是要不断地进行封装才能完善。

  首先socket需要不断地连接,重复的做很麻烦。

  我们需要用到请求发来的一些内容但是字符串提取还需要解析很麻烦。

  我们需要返回一些数据需要设定一些内容也很麻烦。

所以http的解析和http的设定都交给web服务器来搞定。 wsgi是Python里面非常厉害的一个web服务器

我们先看看浏览器发给我们的内容:

GET / HTTP/1.1
Host: 127.0.0.1:8001
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36
Sec-Fetch-Dest: document
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
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9 GET /favicon.ico HTTP/1.1
Host: 127.0.0.1:8001
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36
Sec-Fetch-Dest: image
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: no-cors
Referer: http://127.0.0.1:8001/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9

基于wsgi服务器的框架,帮我们建立封装socket对象,帮我们解析http并帮我们设置响应头。

# 导入socket模块
import socket # python内置的web服务器,我们可以用它做检测用
# 我们引入这个模块下的函数make_server,但是这个函数时类实例化完成的。
from wsgiref.simple_server import make_server def application(environ,start_response):
start_response("200 ok",[('content-type','text/html')])
return [b'<h1>Hello zrg!</h1>'] # make_server(ip地址,端口号,一个函数名字)
# 创建好socket对象并帮我们执行函数
httpd = make_server('',8080,application) # 来启动整个程序
httpd.serve_forever()

start-response是帮我们设定响应头,第一个参数是状态码,第二个参数是一个列表,列表里面是一个元组,每一个元组是一个键值对,而每一个键值对就是我们响应头。如果想给响应头设置什么内容,在这里仅仅写一个元组就可以了。

environ是一个请求字典对象,是wsgi把请求的数据都解析封装好了。我们需要拿哪个键的时候直接通过这个字典然后写键就可以拿到值了。

return 返回的就是响应体了。

根据不同路径返回不同的内容:

# __author:zhangrenguo
# date: # 导入socket模块
import socket # python内置的web服务器,我们可以用它做检测用
# 我们引入这个模块下的函数make_server
from wsgiref.simple_server import make_server def application(environ, start_response):
start_response("200 ok", [('content-type', 'text/html')])
# return [b'<h1>Hello zrg!</h1>']
# 拿到url路径
# print('environ的内容',environ)
# print(environ['PATH_INFO'])
path = environ['PATH_INFO']
if path == '/index':
return [b'<h1>index!</h1>']
elif path == '/book':
return [b'<h1>book!</h1>']
else:
return [b'<h1>404</h1>'] # make_server(ip地址,端口号,一个函数名字)
# 创建好socket对象并帮我们执行函数
httpd = make_server('', 8088, application) # 来启动整个程序
httpd.serve_forever()

最基本的判断路径

# __author:zhangrenguo
# date: # 导入socket模块
import socket # python内置的web服务器,我们可以用它做检测用
# 我们引入这个模块下的函数make_server
from wsgiref.simple_server import make_server # def index():
# return [b'<h1>index!</h1>']
def index(request):
return [b'<h1>index!</h1>'] # def book():
# return [b'<h1>book!</h1>']
def book(request):
return [b'<h1>book!</h1>'] def routers():
urlpatterns = [
('/index', index),
('/book', book),
]
return urlpatterns def application(environ, start_response):
start_response("200 ok", [('content-type', 'text/html')]) path = environ['PATH_INFO']
urlpatterns = routers()
func = None
for item in urlpatterns:
if item[0] == path:
func = item[1]
break if func:
return func(environ)
else:
return [b'<h1>404</h1>'] # if path == '/index':
# # return index()
# return index(environ) #可以通过environ去哪请求的信息
# elif path == '/book':
# # return book()
# return book(environ)
# else:
# return [b'<h1>404</h1>'] # make_server(ip地址,端口号,一个函数名字)
# 创建好socket对象并帮我们执行函数
httpd = make_server('', 8089, application) # 来启动整个程序
httpd.serve_forever()

解耦。循环

这样可以直接加路径,加对应的处理函数。

前后端如果交互的话,需要模板!

在HTML里:

在后端代码里:做替换

# __author:zhangrenguo
# date: # 导入socket模块
import socket # python内置的web服务器,我们可以用它做检测用
# 我们引入这个模块下的函数make_server
from wsgiref.simple_server import make_server
import time def index(request):
return [b'<h1>index!</h1>'] def book(request):
return [b'<h1>book!</h1>'] def current_time(request):
cur_time = time.ctime(time.time())
f = open('current_time.html','rb')
data = f.read() data = str(data,'utf8').replace('!cur_time!',str(cur_time)) return [data.encode('utf8')] def routers():
urlpatterns = [
('/index', index),
('/book', book),
('/current_time', current_time),
]
return urlpatterns def application(environ, start_response):
start_response("200 ok", [('content-type', 'text/html')]) path = environ['PATH_INFO']
urlpatterns = routers()
func = None
for item in urlpatterns:
if item[0] == path:
func = item[1]
break if func:
return func(environ)
else:
return [b'<h1>404</h1>'] # make_server(ip地址,端口号,一个函数名字)
# 创建好socket对象并帮我们执行函数
httpd = make_server('', 8083, application) # 来启动整个程序
httpd.serve_forever()

server

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<h1>current_time: !cur_time! </h1>
</body>
</html>

html

四、http协议

请求和响应:

  请求request:浏览器客户端给服务端发请求。

  响应response:服务端给浏览器回复信息。

请求分为请求头和请求体:通过两个换行来分开。请求方式如果是get请求就没有请求体,数据都在url后面。如果是post请求就既有请求头又有请求体,数据都在请求体力。

  请求头是浏览器要告诉server端关于这次请求的一些内容。

响应头是server端告诉浏览器这次回送的一些内容。

响应体就是html文件。

五、web框架的工作模式

  MVC与MTV模式

Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起,模型负责业务对象与数据库的映射(ORM),视图负责与用户的交互(页面),控制器接受用户的输入调用模型和视图完成用户的请求,其示意图如下所示:

Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同,Django的MTV分别是值:

  • M 代表模型(Model): 负责业务对象和数据库的关系映射(ORM)。
  • T 代表模板 (Template):负责如何把页面展示给用户(html)。
  • V 代表视图(View):   负责业务逻辑,并在适当时候调用Model和Template。

除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示:

一般是用户通过浏览器向我们的服务器发起一个请求(request),这个请求回去访问视图函数,(如果不涉及到数据调用,那么这个时候视图函数返回一个模板也就是一个网页给用户),视图函数调用模型,模型去数据库查找数据,然后逐级返回,视图函数把返回的数据填充到模板中空格中,最后返回网页给用户。

1.虚拟环境的安装

2.web应用 C/S  B/S 架构

3.http协议介绍

4.状态码

5.原生socket

6.框架演变

7.项目演变

一、虚拟环境安装

  什么是虚拟环境?

    1.对真实环境的一个拷贝版本

    2.是实时有效的,可以独立存在运行

    3.可以在计算机上拷贝多个虚拟环境

  

  为什么要使用虚拟环境?

    1.保证真实环境的纯净性

    2.框架的多版本共存

    3.方便做版本迭代

    4.降低多框架共存的维护成本

  安装虚拟环境

    一、pycharm 创建

    二、cmd中创建虚拟环境

      第一步:新建一个文件夹专门管理虚拟环境

      第二步:通过pip3 安装虚拟环境

pip3 install virtualenv

      第三步:

二、web应用 架构

c/s          cilent server

b/s          browser server

三、http协议

  

 什么是http协议

# HTTP(HyperText Transport Protocol)是超文本传输协议
# 基于TCP/IP协议基础上的应用层协议,底层实现仍为socket
# 基于请求-响应模式:通信一定是从客户端开始,服务器端接收到客户端一定会做出对应响应
# 无状态:协议不对任何一次通信状态和任何数据做保存
# 无连接:一次连接只完成一次请求-响应,请求-响应完毕后会立即断开连接

http工作原理

# 一次http操作称之为一个事务,工作过程可分为四步
# 1.客户端与服务端建立连接
# 2.客户端发送一个http协议指定格式的请求
# 3.服务器端接收请求后,回应一个http协议指定格式的响应
# 4.客户端将服务器的响应显示展现给用户

\r\n是结束标志。

 状态码

# 1打头:消息通知
# 2打头:请求成功
# 3打头:重定向
# 4打头:客户端错误
# 5打头:服务器端错误

    

# 1.通过pip3安装虚拟环境:
# -- pip3 install virtualenv # 2.前往目标文件夹:
# -- cd 目标文件夹 (D:\Virtualenv) # 3.创建纯净虚拟环境:
# -- virtualenv 虚拟环境名 (py3-env1) # 4.终端启动虚拟环境:
# -- cd py3-env1\Scripts
# -- activate # 5.进入虚拟环境下的python开发环境
# -- python3 # 6.关闭虚拟环境:
# -- deactivate # 7.PyCharm的开发配置
# 添加:创建项目 -> Project Interpreter -> Existing interpreter -> Virtualenv Environment | System Interpreter -> 目标路径下的python.exe
# 删除:Setting -> Project -> Project Interpreter -> Show All

五、原生socket

服务端,前台

服务器后端:

import socket

# 设置响应头(包含响应行)
RESP_HEADER = b'HTTP/1.1 200 OK\r\nContent-type:text/html;charset=utf-8\r\n\r\n'

# 设置服务器socket相关信息
server = socket.socket()
server.bind(('localhost', 8808))
server.listen(5)
print("服务: http://localhost:8808")

while True:
# 获取B以http协议发来的请求
client, address = server.accept()
data = client.recv(1024)
# 数据报文 包含 请求行 请求头 请求体
print(data)

# 手动以http协议完成响应
# 数据报文 包含 响应行 响应头 响应体
client.send(RESP_HEADER)

# /index => 响应主页
# /login => 登录页面
# 错误 => 404
# 数据data, 字节形式 => 字符串形式
strData = str(data, encoding='utf-8')
# 解析请求的数据, 分析得到路由
my_route = strData.split('\r\n')[0].split(' ')[1]

# 后台没有设置的路由,统统以404来处理
dt = b'404'
# 设置的路由返回响应的页面文件
if my_route == '/index':
with open('02_index.html', 'rb') as f:
dt = f.read()
if my_route == '/login':
with open('02_login.html', 'rb') as f:
dt = f.read()

# /favicon.ico该请求是往后台请求标签图标
if my_route == '/favicon.ico':
with open('favicon.ico', 'rb') as f:
dt = f.read()
# 响应体
client.send(dt)
# 一次循环,代表一次响应,也就是一次事务的完成, 要关闭http请求连接
client.close()

Django框架导读的更多相关文章

  1. MVC其实很简单(Django框架)

    Django框架MVC其实很简单 让我们来研究一个简单的例子,通过该实例,你可以分辨出,通过Web框架来实现的功能与之前的方式有何不同. 下面就是通过使用Django来完成以上功能的例子: 首先,我们 ...

  2. Django框架-目录文件简介

    Rhel6.5 Django1.10 Python3.5 Django框架-目录文件简介 1.介绍Django Django:一个可以使Web开发工作愉快并且高效的Web开发框架. 使用Django, ...

  3. Django框架学习

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

  4. django框架的models

    在django的框架设计中采用了mtv模型,即Model,template,viewer Model相对于传统的三层或者mvc框架来说就相当对数据处理层,它主要负责与数据的交互,在使用django框架 ...

  5. Windows上python开发--2安装django框架

    Windows上python开发--2安装django框架 分类: 服务器后台开发2014-05-17 21:22 2310人阅读 评论(2) 收藏 举报 python django 上一篇文章中讲了 ...

  6. MySQL在Django框架下的基本操作(MySQL在Linux下配置)

    [原]本文根据实际操作主要介绍了Django框架下MySQL的一些常用操作,核心内容如下: ------------------------------------------------------ ...

  7. django框架介绍

    主要内容 1.        Django框架发展 2.        Django架构,MTV模式 3.        开发流程 4.        开发实例——Poll python下各种框架 一 ...

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

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

  9. Django - Django框架 简单介绍

    Django框架 简单介绍 本文地址: http://blog.csdn.net/caroline_wendy/article/details/29172271 1. 介绍 Django是一个开放源码 ...

随机推荐

  1. php文件管理,能够点击依照时间,大小,名称排序

    php文件管理.能够点击依照时间.大小,名称排序  本例没实用到jquery 演示   PHP Code <?php    $rootdir="./";    $spacen ...

  2. re库

    一.Re库的主要功能: 函数 功能 re.search() 在一个字符串中搜索匹配正则表达式的第一个位置,返回match对象 re.match() 在一个字符串的开始位置匹配正则表达式,返回match ...

  3. Spark排序与去重遇见的问题

    答案: Spark的distinct是通过聚集去重的,可以简单理解为group by去重: 代码1:是先去重之后再排序取limit20是正确的, 代码2:是先排序之后再到各个节点进行去重之后再limi ...

  4. 【angularjs】使用angular搭建项目,实现隔行换色

    描叙:使用ng-class实现每隔3行换色 代码: <!DOCTYPE html> <html ng-app="myApp"> <head> & ...

  5. ESP8266串口和MQTT服务器消息互传(版本一) 单纯透传+保存WIFI账号信息

    目标 制作一个ESP8266串口和MQTT相互透传的小WIFI,可用手机修改其连接的路由器,由此该模块可以任意加载到各种串口传输的单片机上,完成硬件到云端的传输. 1 实物图 2 MQTT网页测试客户 ...

  6. ganache与metamask

    1.其实ganache其实就相当于一个私有链ganache安装,这个是图形化界面的: 2.(testRpc跟他其实是一个用处,有一个即可,只不过testRpc是非图形化界面.要注意两者都仅运行在內存中 ...

  7. SQLNET.AUTHENTICATION_SERVICES操作系统认证登录的设定

    $ORACLE_HOME/network/admin/sqlnet.ora 如果使用了SQLNET.AUTHENTICATION_SERVICES=(NTS)则说明可以使用OS认证就,只要conn / ...

  8. 2-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案数据篇(数据库简单说明)

    1-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案数据篇(视频总揽) 这里有个教程   http://www.cnblogs.com/best/p/6517755.h ...

  9. vue引入css的两种方式

    方案1.在main.js中引入方式    import '@/assets/css/reset.css' 方案2.在.vue文件的<style/>标签里面引入    @import &qu ...

  10. 并发连接MySQL

    先吐槽一下libmysqlclientAPI的设计, 多个线程同时去connect居然会core掉. 后来Google了一番, 才发现mysql_real_connect不是线程安全的, 需要一些额外 ...