1. 框架概述

web框架是一个为web服务器提供服务的应用程序,专门负责处理用户的动态资源请求.

静态资源: 资源的内容是固定不变的.

动态资源: 资源的内容是动态变化, 数据是从数据库获取的.

静态 web 服务器 使用 tcp 传输数据

1. 导包 socket

2. 创建一个 socket 对象, socket.socket()

端口复用(可选的)

3. 绑定 socket对象.bind((ip, 端口))

4. 监听 socket对象.listen()

5. 等待连接 socket对象.accept()---> 阻塞等待客户端连接,返回一个新的 socket 对象

6. 接收信息(请求报文) recv

7. 发送信息(响应报文) send

8. 关闭套接字 close()

------------------------------------------

web 服务器的工作流程

1. 在浏览器输入 URL 网址

2. 浏览器会访问 DNS 服务器, 做 DNS 解析, 将域名对应的 ip 进行返回

3. 和服务器建立连接(三次握手)

4. 发送请求报文

5. web 服务器接收浏览器发送报文, 解析报文, 判断请求的资源是静态资源还是动态资源

6. 如果是静态资源, web 服务器自己处理,将内容返回

7. 如果是动态资源, 需要将请求交给 web 框架处理

8. web 框架根据 web 服务器发送的请求, 从模板库中读取需要的模版文件, 同时还需要中数据库中查询需要的数据, 将数据和模版文件进行整合,组成完整的数据

9. web 框架将整理后的数据和处理结果发送给 web 服务器

10. web 服务器根据 web 框架发送内容,组成响应报文,发送给浏览器

11. 浏览器将资源进行整合, 显示内容

---5 7 8 9 10 写代码实现---

2. 搭建框架

1. 找到之前书写的静态 web 服务器的代码, 作为 web 服务器使用

import socket

import threading

class HTTPWebServer(object):

def __init__(self):

# 1. 创建 socket

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 设置端口复用

server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

# 2. 绑定端口和 ip

server_socket.bind(('', 8080))

# 3. 设置监听

server_socket.listen(128)

self.server_socket = server_socket # 将这个 socket 作为实例属性

def __del__(self): # 对象销毁的时候调用 close() 方法

self.server_socket.close()

@staticmethod

def __handle_client_request(new_soc, client_ip_port):

# 5. 接收信息(HTTP 请求报文)

buf = new_soc.recv(4096) # 一次性报文

if buf:

# 打印请求报文

# print(buf.decode())

buf = buf.decode()

# 6. 发送信息(HTTP 响应报文)

# 响应行 协议的版本 状态码 状态描述

response_line = "HTTP/1.1 200 OK\r\n"

# 响应头

response_header = "Server:PY\r\nName:py40\r\n"

# 空行(\r\n)

# 响应体, 文件的内容, 读取文件,将文件的内容作为响应体发送

file_name = buf.split(' ', 2)[1]

print(f"请求的资源为{file_name}")

# 访问的资源是 / ---> index.html

if file_name == '/':

file_name = '/index.html'

try:

with open('static' + file_name, 'rb') as f: # rb, 读取出来的直接是 bytes

data = f.read()

except FileNotFoundError:

with open('static/error.html', 'rb') as f:

data = f.read()

# 如果文件不存在, 修改响应行的状态码

response_line = "HTTP/1.1 404 Not Found\r\n"

response = (response_line + response_header + '\r\n').encode() + data

new_soc.send(response)

else:

print(f"{client_ip_port} 断开连接...")

# 7. 关闭连接

new_soc.close()

def start(self):

# 4. 等待连接

print('服务已启动,端口为 8080, 等待连接....')

while True:

new_socket, ip_port = self.server_socket.accept()

print(f"{ip_port} 建立连接......")

# 用户连接之后,创建一个线程

sub_thread = threading.Thread(target=self.__handle_client_request, args=(new_socket, ip_port))

sub_thread.start()

if __name__ == '__main__':

# 创建对象

web = HTTPWebServer()

web.start() # 启动服务器

2. 将 static 文件和 template 文件放到当天的代码目录中

3. 启动 web 服务器, 访问之前的静态页面, 能够正常访问

4. 修改 web 服务器的代码

3. 动态资源判断

判断一个资源是不是动态资源, 只需要判断资源是不是以 .html 结尾 字符串.endswith()

# 此时获取到文件的资源路径,需要判断是静态资源还是动态资源

if file_name.endswith('.html'):

"""动态资源, 交给框架处理"""

# 思考,框架如何知道请求的是哪个页面 ---> 函数传参

# 一般的方法, 将需要传递的数据组成字典传递

# 好处: 可以传递多个数据

env = {

'filename': file_name,

# 还可以传递其他参数,目前不需要

}

status, header, file_data = framework.handle_request(env)

response_line = "HTTP/1.1%s\r\n" % status

response_header = header

data = file_data.encode()

else:

"""静态资源,web 服务器直接自己处理"""

try:

with open('static' + file_name, 'rb') as f: # rb, 读取出来的直接是 bytes

data = f.read()

except FileNotFoundError:

with open('static/error.html', 'rb') as f:

data = f.read()

# 如果文件不存在, 修改响应行的状态码

response_line = "HTTP/1.1 404 Not Found\r\n"

4. 处理客户端的动态资源请求创建web框架程序

接收web服务器的动态资源请求

处理web服务器的动态资源请求并把处理结果返回给web服务器

web服务器把处理结果组装成响应报文发送给浏览器

web框架程序(framework.py)代码:

"""miniweb框架,负责处理动态资源请求"""

import time

# 获取首页数据

def index():

# 响应状态

status = "200 OK";

# 响应头

response_header = [("Server", "PWS2.0")]

# 处理后的数据

data = time.ctime()

return status, response_header, data

# 没有找到动态资源

def not_found():

# 响应状态

status = "404 Not Found";

# 响应头

response_header = [("Server", "PWS2.0")]

# 处理后的数据

data = "not found"

return status, response_header, data

# 处理动态资源请求

def handle_request(env):

# 获取动态请求资源路径

request_path = env["filename"]

print("接收到的动态资源请求:", request_path)

if request_path == "/index.html":

# 获取首页数据

result = index()

return result

else:

# 没有找到动态资源

result = not_found()

return result

5. 路由列表开发

路由: 请求的 URL 到到处理的函数之间的关系

5.1 在路由列表添加路由

# 定义路由列表, 在列表中保存所有的请求资源和处理函数的对应关系(Django)

route_list = [

('/index.html', index), # 函数地址的引用, 不能加括号的

('/center.html', center)

]

def handle_request(env):

"""处理动态资源请求"""

# 1. 获取web 服务器传递的参数

file_name = env['filename'] # 通过字典的key 取值

print(f'接收到要处理的动态资源是: {file_name}')

# 遍历路由列表, 查找需要请求的资源是否在路由列表中

for route in route_list:

if file_name == route[0]:

func = route[1] # func 是一个函数

return func() # return route[1]()

else:

return not_found()

5.2 装饰器方式的添加路由

route_list = []

def my_route(filename):

# 定义装饰器

def decorator(fn):

# 添加路由

# route_list.append((filename, fn))

def inner():

return fn()

route_list.append((filename, inner))

return inner

return decorator

@my_route('/index.html')

def index(): # 视图函数

"""专门用来处理首页数据的"""

# 1. 从模板库读取 html 页面

with open('template/index.html', 'r') as f:

file_data = f.read()

6. 数据库准备将提前给到大家的 stock_db.sql 复制到 Ubuntu 桌面中

登录 mysql 客户端 mysql -uroot -pmysql

创建数据库 create database stock_db charset=utf8;

使用这个数据库use stock_db

导入 SQL 语句 source ~/Desktop/stock_db.sql

7. index 页面处理从数据库获取数据

使用这个数据进行模版替换

# 获取首页数据

@route("/index.html")

def index():

# 响应状态

status = "200 OK";

# 响应头

response_header = [("Server", "PWS2.0")]

# 打开模板文件,读取数据

with open("template/index.html", "r") as file:

file_data = file.read()

# 处理后的数据, 从数据库查询

conn = pymysql.connect(host="localhost",

port=3306,

user="root",

password="mysql",

database="stock_db",

charset="utf8")

# 获取游标

cursor = conn.cursor()

# 查询sql语句

sql = "select * from info;"

# 执行sql

cursor.execute(sql)

# 获取结果集

result = cursor.fetchall()

print(result)

data = ""

for row in result:

data += '''

%s%s%s%s%s%s%s%s''' % row

# 替换模板文件中的模板遍历

result = file_data.replace("{%content%}", data)

return status, response_header, result

8. center 页面处理

前后端分离后端程序员提供数据接口

前端程序员,在页面 发送 Ajax 请求,获取数据,解析数据,将数据显示到页面中

8.1 后端

# 个人中心数据接口开发

@route("/center_data.html")

def center_data():

# 响应状态

status = "200 OK";

# 响应头

response_header = [("Server", "PWS2.0"), ("Content-Type", "text/html;charset=utf-8")]

conn = pymysql.connect(host="localhost",

port=3306,

user="root",

password="mysql",

database="stock_db",

charset="utf8")

# 获取游标

cursor = conn.cursor()

# 查询sql语句

sql = '''select i.code, i.short, i.chg,i.turnover, i.price, i.highs, f.note_infofrom info as i inner join focus as f on i.id = f.info_id;'''

# 执行sql

cursor.execute(sql)

# 获取结果集

result = cursor.fetchall()

# 关闭游标

cursor.close()

# 关闭数据库连接

conn.close()

# 个人中心数据列表

center_data_list = list()

# 遍历每一行数据转成字典

for row in result:

# 创建空的字典

center_dict = dict()

center_dict["code"] = row[0]

center_dict["short"] = row[1]

center_dict["chg"] = row[2]

center_dict["turnover"] = row[3]

center_dict["price"] = str(row[4])

center_dict["highs"] = str(row[5])

center_dict["note_info"] = row[6]

# 添加每个字典信息

center_data_list.append(center_dict)

# 把列表字典转成json字符串, 并在控制台显示

json_str = json.dumps(center_data_list,ensure_ascii=False)

print(json_str)

return status, response_header, json_str

代码说明:json.dumps函数把字典转成json字符串

函数的第一个参数表示要把指定对象转成json字符串

参数的第二个参数ensure_ascii=False表示不使用ascii编码,可以在控制台显示中文。

响应头添加Content-Type表示指定数据的编码格式

8.2 前端

// 发送ajax请求获取个人中心页面数据

$.get("center_data.html", function (data) {

var data_array = data;

// 获取table标签对象

var $table = $(".table")

for(var i = 0; i < data_array.length; i++){

// 获取每一条对象

var center_obj= data_array[i];

var row_html= '

' +

'

'+ center_obj.code +'' +

'

'+ center_obj.short +'' +

'

'+ center_obj.chg +'' +

'

'+ center_obj.turnover +'' +

'

'+ center_obj.price +'' +

'

'+ center_obj.highs +'' +

'

'+ center_obj.note_info +'' +

'

修改 ';

// 为table标签添加每一行组装的html数据

$table.append(row_html);

}

}, "json");

python就业班 miniweb框架_mini-web框架相关推荐

  1. python就业班 miniweb框架_Python“mini-web”项目实战再度来袭!同学们厉害了

    4月30日,传智专修学院Python应用开发方向的同学们迎来本学期首次项目答辩,此次项目聚焦专业知识,以 "mini-web" 为主题,集中展示多样化的项目作品. 本次项目内容分为 ...

  2. 什么是Web框架、web框架有什么功能?

    随着Web最新发展趋势的不断升级,Web项目开发也越来越难,而且需要花费更多的开发时间.所以,Web程序员灵活运用Web开发框架显得更为重要.下面为大家简单的介绍一下Web框架的基本内容,希望对大家有 ...

  3. Python学习笔记:Day5 编写web框架

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  4. python框架sanic_Python Web框架Sanic框架初识

    Sanic 既是一个Python web 服务器,又是一个web框架,它为速度而生.Sanic只支持Python 3.5及其以上版本,允许我们使用 async/await 语法来使我们的代码非阻塞且快 ...

  5. 它号称 Python 中性能最高的异步 Web 框架:超详细 Sanic 入门指南!

    △点击上方"Python猫"关注 ,回复"2"加入交流群 作者:古明地盆 来源:https://www.cnblogs.com/traditional/p/14 ...

  6. 自定义python框架_Python web 框架Sanic 学习: 自定义 Exception

    Sanic 是一个和类Flask 的基于Python3.5+的web框架,它使用了 Python3 异步特性,有远超 flask 的性能. 编写 RESTful API 的时候,我们会定义特定的异常错 ...

  7. python django flask介绍_Python开发WEB框架Flask详细介绍

    Flask简介 Flask是一个相对于Django而言轻量级的Web框架. 和Django大包大揽不同,Flask建立于一系列的开源软件包之上,这其中 最主要的是WSGI应用开发库Werkzeug和模 ...

  8. 2020年黑马python视频教程5.0新版课程_黑马Python就业班5.0-最新2020人工智能

    2020年最新版Python5.0,全新升级!人工智能数据分析,爬虫,机器学习,WEB全栈开发 Python开发特训班课程,以实战项目出发, 将部署运维和测试开发内容整合的项目中, 真正让学员参与到实 ...

  9. zk框架_ZK Web框架思想

    zk框架 我曾多次被要求提出一些有关ZK的意见. 因此,根据我4年作为ZK用户的经验,有一些想法: 总体开发人员经验,社区和文档 "就是这样" ZK提供的大多数东西都能很好地工作, ...

最新文章

  1. FRAME与IFRAME
  2. 5G时代的CDN将会怎么样?
  3. 显示纯服务器_不止于手机!华为台式机真的来了,网友:这次真的“纯国产”...
  4. HDU 1556 前缀和 树状数组 线段树
  5. ts定义数组类型_ts基本数据类型
  6. sap获取系统时间_获取系统当前时间
  7. stl向量_如何检查C ++ STL中向量中是否存在元素?
  8. DTW算法——Matlab实现
  9. 使用Visual studio查看exe或DLL文件的依赖项
  10. 概率统计笔记:二维随机变量及其联合概率分布
  11. 机器学习自动写诗-学习笔记
  12. 达人评测 小米平板5pro和苹果ipad9选哪个好
  13. #cs231n#Assignment2:Dropout.ipynb
  14. 卡马克揭开VR延迟背后的真相
  15. [ARM] ARM处理器的7种工作模式和2种工作状态
  16. 15-Puzzle Problem
  17. 常用嵌入式软件白盒测试工具介绍
  18. 微信小程序图片空白问题处理
  19. GCD入门(二): 多核心的性能
  20. The referenced script on this Behaviour is missing 如何把这个警告解决-很简单

热门文章

  1. 捕获Java堆转储的7个选项
  2. visualvm远程jvm_如何使用VisualVM监视服务器上的多个JVM
  3. 带有Oracle Digital Assistant和Fn Project的会话式UI
  4. Java的未来项目:巴拿马,织布机,琥珀和瓦尔哈拉
  5. java 批量处理 示例_Java异常处理教程(包含示例和最佳实践)
  6. 背压加载文件– RxJava常见问题解答
  7. Kafka Connect在MapR上
  8. 跨站点脚本(xss)_跨站点脚本(XSS)和预防
  9. 关于避免对toString()结果进行解析或基于逻辑的美德
  10. Swing应用程序中的CDI事件可将UI与事件处理分离