手动搭建简易web框架与django框架简介
纯手写简易web框架
第一步:搭建简易版本服务端
import socket
server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)
while True:
sock, addr = server.accept()
data = sock.recv(1024).decode('utf8')
print(data)
sock.send(b'hello')
第二步:遵循HTTP协议给浏览器发送消息
import socket
server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)
while True:
sock, addr = server.accept()
data = sock.recv(1024).decode('utf8')
print(data)
sock.send(b'HTTP1.1 200 OK\r\n\r\n')
sock.send(b'hello world!')
第三步:启动服务端后浏览器输入127.0.0.1:8080测试是否能获取服务端的消息
第四步:基于不同的后缀响应不同的内容,如:127.0.0.1:8080/login、127.0.0.1:8080/register
import socket
server = socket.socket()
server.bind(('127.0.0.1',8080))
server.listen(5)
while True:
sock, addr = server.accept()
data = sock.recv(1024).decode('utf8')
sock.send(b'HTTP1.1 200 OK\r\n\r\n')
# 切割浏览器的请求消息,只获取后缀内容
new_data = data.split(' ')[1]
# 根据后缀的不同返回不同的内容
if new_data == '/login':
sock.send(b'welcome login')
elif new_data == '/register':
sock.send(b'welcome register')
else:
sock.send(b'404 error')
搭建完成,但是这种搭建方式有许多缺陷:
- 服务端起始代码过于重复
- 针对HTTP请求数据没有完善的处理方式
- 并发量问题
基于wsgiref模块
wsgiref模块可以帮你快速处理请求数据与响应数据,这个模块会把请求数据处理成字典类型的数据。
利用wsgiref模块搭建服务端
from wsgiref import simple_server
def run(request, response):
"""
:param request: 请求相关的数据
:param response: 响应相关的数据
:return: 返回给客户端的展示数据
"""
print(request) # 查看请求数据
response('200 OK', []) # 固定编写,遵循http协议
current_path = request.get("PATH_INFO") # 获取ip地址中的后缀
if current_path == '/login':
return [b'welcome login']
elif current_path == '/register':
return [b'welcome register']
return [b'404 error']
if __name__ == '__main__':
server = simple_server.make_server('127.0.0.1', 8080, run)
'''一致监听本机8080端口 一旦有请求访问 自动触发run方法的执行'''
server.serve_forever() # 服务端永久运行
缺陷:
- 如果网站很多,是不是就是一味的添加elif
- 每个分支下的功能根据业务逻辑的不同可能会比较复杂
优化
第一步:将匹配和功能封装成元组和函数
from wsgiref import simple_server
def login():
return 'welcome login'
def register():
return 'welcome register'
urls = (
('/login', login),
('/register', register),
)
def run(request, response):
"""
:param request: 请求相关的数据
:param response: 响应相关的数据
:return: 返回给客户端的展示数据
"""
print(request) # 查看请求数据
response('200 OK', []) # 固定编写,遵循http协议
current_path = request.get("PATH_INFO") # 获取ip地址中的后缀
for url in urls:
if current_path == url[0]:
res = url[1]()
break
else:
res = '404 error'
return [res.encode('utf8')]
if __name__ == '__main__':
server = simple_server.make_server('127.0.0.1', 8080, run)
'''一致监听本机8080端口 一旦有请求访问 自动触发run方法的执行'''
server.serve_forever() # 服务端永久运行
第二步:根据功能的不同拆分成不同的py文件
views.py:业务逻辑的编写
def login(request):
return 'welcome login'
def register(request):
return 'welcome register'
urls.py:存储对应关系
from views import *
urls = (
('/login', login),
('/register', register),
)
服务端:
from wsgiref import simple_server
from urls import urls
def run(request, response):
response('200 OK', []) # 固定编写,遵循http协议
current_path = request.get("PATH_INFO") # 获取ip地址中的后缀
for url in urls:
if current_path == url[0]:
res = url[1](request)
break
else:
res = '404 error'
return [res.encode('utf8')]
if __name__ == '__main__':
server = simple_server.make_server('127.0.0.1', 8080, run)
'''一致监听本机8080端口 一旦有请求访问 自动触发run方法的执行'''
server.serve_forever() # 服务端永久运行
基于上述优化之后,整个项目结构清晰,管理维护都很方便!并且拆分完后以后要想新增功能,只需要在urls.py中添加对应关系 view.py中编写函数。
补充
业务函数的代码中,可能会频繁的使用到不同的html页面,为了避免文件类型的混乱,会单独开设一个文件夹存储所有的html文件:templates文件夹。
项目中的html文件,也有可能需要用到css、js、第三方框架文件,这些文件都是很少做改动的文件,可以统一放到:static文件夹。
动静态网页
静态网页:页面上的数据是不会改变的。
动态网页:页面上的数据是通过代码动态获取的,实时可变。
编写简易动态网页
第一步:在项目的templates文件夹下创建get_time.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>时间:time_show</p>
</body>
</html>
第二步:在上面代码的基础上,对views.py和urls.py文件添加以下内容:
views.py:添加新函数
def get_time(request):
# 1.获取当前时间
import time
c_time = time.strftime('%Y-%m-%d %X')
# 2.读取html文件
with open(r'templates/get_time.html', 'r', encoding='utf8') as f:
data = f.read()
# 3.思考:如何给字符串添加一些额外的字符串数据>>>:字符串替换
new_data = data.replace('time_show', c_time)
return new_data
urls.py:修改urls变量
from views import *
urls = (
('/login', login),
('/register', register),
('/get_time', get_time),
)
运行服务端,输入127.0.0.1/get_time,此时展示的页面就是动态页面,每次刷新都会从后端获取数据并更新。
这种方式前端无法操作传来的数据,那么如果想要让前端可以操作数据呢?比如把字典传过去,让前端自行操作字典类型数据,这就需要用到一个第三方模块:jinja2模块。
简单了解jinja2模块
在编写前后端不分离项目的时候,可以使用该模块提供的模板语法简单快速的在html页面是使用类似于后端的代码语法操作数据。
jinja2模块属于第三方模块,需要自行下载:
pip install jinja2
在项目的templates文件夹下创建get_dict.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<p>字典展示</p>
<p>{{ user.name }}</p>
<p>{{ user.pwd }}</p>
<p>{{ user.hobby }}</p>
<p>列表循环展示</p>
<p>
{% for i in new_list %}
<span>元素:{{ i }}</span>
{% endfor %}
</p>
</body>
</html>
views.py:添加函数
from jinja2 import Template
def get_dict(request):
user_dict = {'name': 'jason', 'pwd': 123, 'hobby': 'read'}
new_list = [11, 22, 33, 44, 55, 66]
with open(r'templates/get_dict.html', 'r', encoding='utf8') as f:
data = f.read()
temp_obj = Template(data)
res = temp_obj.render({'user':user_dict,'new_list':new_list})
# 给页面传递一个变量名是user 值是user_dict对应的值的数据
return res
urls.py:修改urls变量:
from views import *
urls = (
('/login', login),
('/register', register),
('/get_time', get_time),
('/get_dict', get_dict),
)
访问127.0.0.1/get_dict。
框架请求流程
仅限于我们自己编写的web框架
urls.py:路由层
- 后缀与函数名对应关系
- 后缀专业名词称之为'路由'
- 函数名专业名词称之为'视图函数'
views.py:视图层
- 专门编写业务逻辑代码
- 可以是函数,也可以是类
- 函数专业名词称之为'视图函数'
- 类专业名词称之为'视图类'
templates文件夹:模板层
- 专门存储html文件
- html文件专业名词称之为'模板文件'
python主流web框架
django:大而全,自带的功能非常的多,但是有时候会略显笨重,类似于'航空母舰'。
flask:小而精,自带的功能非常的少,但是第三方模块非常的多,类似于'游骑兵'。
flask的第三方模块加到一起甚至比django还多,并且也越来越像django;flask由于过多的依赖于第三方模块,有时候也会受制于第三方模块。
tornado:异步非阻塞框架,速度极快,甚至可以用于充当游戏服务器。
django框架
简介
版本
- django3.X:默认支持异步功能
- django2.X:默认不支持异步
- django1.X:默认不支持异步
下载使用
建议使用1.11.X版本
pip install django==1.11.11
验证是否下载成功
cmd窗口直接输入django-admin,有反应就是成功了。
应用app
django本身类似于是一个空壳子,真正的功能是由里面的各个应用决定。django框架就相当于是一所大学,应用相当于是大学里面的各个学院。
在使用django框架时,会先创建一个空的django项目,然后根据功能的不同创建不同的应用。
创建应用之后,一定要去配置文件中注册才能生效。
比如我创建一个应用,名为app01,创建后给settings.py文件中INSTALLED_APPS配置添加应用名称。
命令操作django
1.创建django项目
django-admin startproject 项目名
2.进入django项目目录
cd 项目名
3.创建app应用
python manage.py startapp 应用名
4.启动django项目
python manage.py runserver IP地址:端口号
5.浏览器访问IP地址:端口号
pycharm操作django
1.file-->new project,选择django,输入信息,创建,选择此窗口打开。
2.创建应用:tools-->Run manage.py Task
在弹出来的终端输入创建应用命令:
startapp 应用名
3.修改端口号:
4.启动项目:
5.浏览器访问
django主要文件介绍
djangoProject:项目文件名
{
app01:应用文件夹
{
migrations文件夹:数据迁移记录
admin.py:django自带的后台管理
apps.py:用于app的注册
models.py:专门用于操作数据库
views.py:视图层
}
djangoProject:项目同名文件夹
{
settings.py:项目配置文件
urls.py:路由层
}
templates:模板层
manage.py:django入口文件,很多命令都需要该文件支持
db.sqlite3:django启动之后才会生成的文件,其实就是django自带的小型数据库
}
手动搭建简易web框架与django框架简介的更多相关文章
- express搭建简易web的服务器
express搭建简易web的服务器 说到express我们就会想到nodejs,应为它是一款基于nodejs平台的web应用开发框架.既然它是基于nodejs平台的框架那么就得先安装nodejs. ...
- 搭建简易Web GIS网站:使用GeoServer+PostgreSQL+PostGIS+OpenLayers3
Web GIS系列: 搭建简易Web GIS网站:使用GeoServer+PostgreSQL+PostGIS+OpenLayers3 使用GeoServer+QGIS发布WMTS服务 使用GeoSe ...
- wsgiref模块、web框架、django框架简介
"""web框架:将前端.数据库整合到一起的基于互联网传输的python代码 web框架也可以简单的理解为是软件开发架构里面的'服务端'""" ...
- web框架和Django框架的初识
1,web框架的原理 1.1>c/s架构和b/s架构 1>c/s客户端模式 2>B/S浏览器模式-----web开发(web开发开的是B/S架构) 1.2>web开发的本质 1 ...
- 如何在asp.net mvc框架及django框架下面避免CSRF
CSRF 跨站伪造请求 不知CSRF为何物的,可以问下G哥. 在Asp.net MVC平台下,提供了Html.AntiForgeryToken() 方法,我们只需把其放在form的标签内,在浏览器端就 ...
- [oldboy-django][1初始django]web框架本质 + django框架 + ajax
web框架本质 浏览器(socket客户端) - 发送请求(ip和端口,url http://www.baidu.com:80/index/) - GET 请求头(数据请求行的url上: Http1. ...
- MyBatis整合Spring+SpringMVC搭建一个web项目(SSM框架)
本文讲解如何搭建一个SSM架构的web站点 [工具] IDEA.SqlYog.Maven [简述] 该项目由3个模块组成:dao(数据访问层).service(业务处理层).web(表现层) dao层 ...
- 手动搭建ABP2.1.3 Zero——基础框架
一.基础层搭建 二.PM.Core 三.PM.EntityFramework 四.PM.Application 五.PM.WebApi 六.PM.Web(MPA) 七.PM.Web(SPA) 八.单元 ...
- web开发中的MVC框架与django框架的MTV模式
1.MVC 有一种程序设计模式叫MVC,核心思想:分层,解耦,分离了 数据处理 和 界面显示 的代码,使得一方代码修改了不会影响到另外一方,提高了程序的可扩展性和可维护性. MVC的全拼为Model- ...
随机推荐
- 细说Web API中的Blob
在一般的Web开发中,很少会用到Blob,但Blob可以满足一些场景下的特殊需求.Blob,Binary Large Object的缩写,代表二进制类型的大对象.Blob的概念在一些数据库中有使用到, ...
- Codepen 每日精选(2018-3-24)
按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以打开原始页面. 纯 css 画的抽象小鸟https://codepen.io/gregoryb/f... 纯 css 制作 ...
- Jedis的基本操作
jedis jedis 是 redis推荐的java客户端.通过Jedis我们可以很方便地使用java代码的方式,对redis进行操作.jedis使用起来比较简单,它的操作方法与redis命令相类似. ...
- Java多线程与线程池技术
一.序言 Java多线程编程线程池被广泛使用,甚至成为了标配. 线程池本质是池化技术的应用,和连接池类似,创建连接与关闭连接属于耗时操作,创建线程与销毁线程也属于重操作,为了提高效率,先提前创建好一批 ...
- 3道常见的vue面试题,你都会了吗?
最近流传各大厂纷纷裁员,导致很多人"被迫"毕业,显然很多人还是想留级,无奈出现在名单中,只能感叹命运不公,不过拿了N+1,也算是很欣慰. 又得去面试了,接下来一起来巩固下vue的3 ...
- [翻译] 使用 TensorFlow 进行分布式训练
本文以两篇官方文档为基础来学习TensorFlow如何进行分布式训练,借此进入Strategy世界.
- JavaWeb学习day7-Response初学4
重定向和转发的区别 相同 页面都会实现跳转 不同 请求转发的时候url不会发生变化,编码是307 重定向的时候url会变化,编码是302
- Vue 中 axios 跨域配置 (!!!配置完成需要重新运行,不然也不起作用)
当拿到一个网址如:https://music.163.com/store/api/categorypage/list 获取数据是出现如下: 证明该网址不能非常直观的拿到数据.接下来我们试试跨域拿这个 ...
- Casdoor + OAuth 实现单点登录 SSO
简介 Casdoor 是一个基于 OAuth 2.0 / OIDC 的中心化的单点登录(SSO)身份验证平台,简单来说,就是 Casdoor 可以帮你解决用户管理的难题,你无需开发用户登录.注册等与用 ...
- redis 知识点收集 注意理解底层
学redis,首先要明白其特性,其次要理解明白redis与操作系统底层的关系,这点很重要.这是一个优秀的学习方法,作为计算机专业,应当时刻想着技术和操作系统计算机组成数据结构的联系,听起来有些书生气死 ...