一、前言

二、框架结构及实现流程

三、总结

一、前言

  当我们了解了Web应用和Web框架,以及HTTP协议的原理之后,我们可以自己动手DIY一个最简单的WEB框架,以加深对Web框架的理解,并为即将学习的Django探探路。

二、框架结构及实现流程

  1.框架结构的内容如下图所示

  我们DIY的这个Web框架按照启动的先后顺序,大致分为这样几个部分,分别是models.py、manage.py、urls.py、views.py、templates(html文件)五个部分,下面我们分别对这五个部分进行实现,最后,进行运行测试,验证框架的的可用性。

  2.实现流程

  (1) models.py -- 与数据库相关的,在我们的项目启动前,利用models.py在数据库中创建表结构,注意,仅运行一次。

#!/usr/bin/env python3
#!-*- coding:utf-8-*-
# write by cc import pymysql # 1.建立连接
conn = pymysql.connect(
host = 'localhost',
port = 3306,
user = 'cc1',
password = 'cc111',
db = 'db1',
charset = 'utf8'
) # 2.获取游标
cursor = conn.cursor()
# cursor = conn.cursor(pymysql.cursor.DictCursor) # 设游标类型为字典类型 # 3.执行sql语句
sql = "create table users(id int,user char(12),pwd char(12))"
rows = cursor.execute(sql)
print(rows) # 打印受影响的记录条数 # 4.提交(必须提交,才能实现操作)
conn.commit() # 5.关闭游标和连接
cursor.close()
conn.close()

  (2) manage.py -- 项目的启动文件

from wsgiref.simple_server import make_server

from urls import url_list

def application(environ,start_response):
path = environ.get("PATH_INFO")
print(path)
start_response("200 OK",[('Content-Type','text/html')]) func = None
for item in url_list:
if path == item[0]:
func = item[1]
break
if func:
return [func(environ)]
else:
return [b'404 Not found'] if __name__ == '__main__':
httpd = make_server("",8080,application) # 指定端口
print('Serving HTTP on port 8080...')
httpd.serve_forever() # 开启监听

  (3) urls.py -- url控制器,反映路径与视图函数的映射关系

from app01.views import *

url_list = [
('/favcion.ico',fav),
('/index',index),
('/login',login),
('/reg',reg),
('/timer',timer),
('/auth',auth)
]

  (4) views.py -- 视图函数,固定接收一个形式参数:environ

from urllib.parse import parse_qs
def fav(environ):
with open('templates/favcion.ico','rb') as f:
data = f.read()
return data def index(environ):
with open('templates/index.html','rb') as f:
data = f.read()
return data def login(environ):
with open('templates/login.html','rb') as f:
data = f.read()
return data def reg(environ):
with open('templates/reg.html','rb') as f:
data = f.read()
return data def timer(environ):
import datetime
now = datetime.datetime.now().strftime("%y-%m-%d %X")
return now.encode('utf-8') def auth(environ):
try:
request_body_size = int(environ.get('CONTENT_LENGTH',0))
except(ValueError):
request_body_size = 0
request_body = environ['wsgi.input'].read(request_body_size)
data = parse_qs(request_body) # 解析出用户输入的用户名和密码
user = data.get(b'user')[0].decode('utf8')
pwd = data.get(b'pwd')[0].decode('utf8') # 连接数据库
import pymysql
conn = pymysql.connect(host='localhost',port=3306,user='cc1',password='cc111',db='db1',charset='utf8') # 创建游标
cursor = conn.cursor() # 执行数据查询、插入等操作
sql = 'select * from users where user=%s and pwd=%s'
cursor.execute(sql,(user,pwd)) # 验证是否能取出相关记录
if cursor.fetchone():
print(cursor.fetchone())
f = open('templates/backend.html','rb')
data = f.read()
data = data.decode('utf8')
return data
else:
return b'user or password is wrong'

  (5) templates -- 储存 html 文件,当用户输入的路径正确存在与url控制器中时,为用户展示指定的页面。

  favcion.ico 是一个缩略图,可自由指定。

  index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>Hello world!</h1>
<h2>Boys and girls!</h2>
<h3><a href="https://www.cnblogs.com/schut"/>This is my web</a></h3>
<img src="https://pic.cnblogs.com/avatar/1209144/20170813234607.png">
</body>
</html>

  login.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<h1>Hello world!</h1>
<h2>Boys and girls!</h2>
<form action="http://127.0.0.1:8080/auth" method="post">
姓名<input type="text" name="user">
密码<input type="password" name="pwd">
<input type="submit">
</form>
</body>
</html>

  reg.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册页面</title>
</head>
<body>
<h3>欢迎来到注册页面</h3>
<form action="" method="post">
用户名:<input type="text" name="username"><br/>
密 码:<input type="password" name="pwd"><br/>
再次输入密码:<input type="password" name="pwd2"><br/>
<input type="submit">
<input type="reset">
</form>
</body>
</html>

  backend.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<h2>欢迎登录</h2>
</body>
</html>

三、总结

  以上DIY的简易框架,大致可以分为五个部分,各自承担不同的作用,缺一不可。

manage.py -- 启动文件,封装socket

1   urls.py -- 路径与视图函数的映射关系 ------------- url控制器
2 views.py -- 视图函数,固定接收一个形式参数:environ ------- 视图函数
3 templates文件夹 -- html文件 -------模板
4 models --在项目启动前,在数据库中创建表结构 ----- 与数据库相关

  

DIY一个Web框架的更多相关文章

  1. 2、基于wsgiref模块DIY一个web框架

    一 web框架 Web框架(Web framework)是一种开发框架,用来支持动态网站.网络应用和网络服务的开发.这大多数的web框架提供了一套开发和部署网站的方式,也为web行为提供了一套通用的方 ...

  2. 第一个web框架tornado

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

  3. Go语言笔记[实现一个Web框架实战]——EzWeb框架(一)

    Go语言笔记[实现一个Web框架实战]--EzWeb框架(一) 一.Golang中的net/http标准库如何处理一个请求 func main() { http.HandleFunc("/& ...

  4. 手把手和你一起实现一个Web框架实战——EzWeb框架(二)[Go语言笔记]Go项目实战

    手把手和你一起实现一个Web框架实战--EzWeb框架(二)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 上一篇文章我们实现了框架的雏形,基本地 ...

  5. 手把手和你一起实现一个Web框架实战——EzWeb框架(三)[Go语言笔记]Go项目实战

    手把手和你一起实现一个Web框架实战--EzWeb框架(三)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 本篇代码,请选择demo3 这一篇文章 ...

  6. 手把手和你一起实现一个Web框架实战——EzWeb框架(四)[Go语言笔记]Go项目实战

    手把手和你一起实现一个Web框架实战--EzWeb框架(四)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 这一篇文章主要实现路由组功能.实现路由 ...

  7. 手把手和你一起实现一个Web框架实战——EzWeb框架(五)[Go语言笔记]Go项目实战

    手把手和你一起实现一个Web框架实战--EzWeb框架(五)[Go语言笔记]Go项目实战 代码仓库: github gitee 中文注释,非常详尽,可以配合食用 本篇代码,请选择demo5 中间件实现 ...

  8. Python高级网络编程系列之终极篇---自己实现一个Web框架

    通过前面几个小节的学习,现在我们想要把之前学到的知识点给串联起来,实现一个很小型的Web框架.虽然很小,但是用到的知识点都是比较多的.如Socket编程,装饰器传参在实际项目中如何使用.通过这一节的学 ...

  9. luci框架-LUA的一个web框架使用

    转自:http://blog.csdn.net/initphp/article/details/17527639 LUCI 这个在百度上搜索除了一篇我的百度文库 luci 的介绍文章之外,前三页都是些 ...

随机推荐

  1. koa post提交数据,koa-bodyparser中间件来获取post提交数据

    原生 Nodejs 获取 post 提交数据 首先创建并初始化一个node应用,根路由使用index.ejs模板 var Koa=require('koa') var router = require ...

  2. D3.js的v5版本入门教程(第七章)—— 比例尺的使用

    D3.js的v5版本入门教程(第七章) 比例尺在D3.js中是一个很重要的东西,我们可以这样理解d3.js中的比例尺——一种映射关系,从domain映射到range域(为什么会是domain和rang ...

  3. 刷题记录:[CISCN 2019 初赛]Love Math

    目录 刷题记录:[CISCN 2019 初赛]Love Math 思路一 思路二 总结 刷题记录:[CISCN 2019 初赛]Love Math 题目复现链接:https://buuoj.cn/ch ...

  4. 升级pip后,出现ImportError:cannot import name main

    升级pip后,出现ImportError错误,如下图: 解决方法: sudo gedit /usr/bin/pip 进去后修改为 from pip import __main__ if __name_ ...

  5. 009-MySQL循环while、repeat、loop使用

    一.循环使用 mysql常见的三种循环方式:while.repeat和loop循环.还有一种goto,不推荐使用. 前提1.创建基本表结构 # 创建表结构 drop table if exists ` ...

  6. Spring cloud微服务安全实战-7-11PinPoint+SpringBoot环境搭建

    微服务的最后一个组件, 调用链监控,一个请求进来以后,经过N多个微服务,例如a调用了b.b又调用了c,那么在这个过程中看到,整个的调用的链路,然后每一段调用所耗费的时间,帮你去分析你的系统如果出现瓶颈 ...

  7. 使用ObjectARX 2012向导生成的自定义实体类无法捕捉的问题解决方式

    使用ObjectARX 2012自定实体向导的时候,获取捕捉点的重写函数的向导中模板有点问题, C:\Program Files (x86)\Autodesk\ObjectARX 2019 Wizar ...

  8. Springboot项目中异常拦截设计与处理

    背景: 项目运行过程中会出现各种各样的问题,常见的有以下几种情况: 业务流程分析疏漏,对业务流程的反向操作.边界分析设计不充分 调用外部服务.调用外部系统出现的超时.错误.返回值与预期不符 外部资源连 ...

  9. k8s 使用本地镜像的时候

    k8s默认会从远端拉取镜像,其配置参数imagePullPolicy为Always containers: - name: demo image: image imagePullPolicy: Nev ...

  10. canal部署启动的时候报错com.alibaba.druid.pool.DruidDataSource - testWhileIdle is true, validationQuery not set

    报错信息:com.alibaba.druid.pool.DruidDataSource - testWhileIdle is true, validationQuery not set 解决方法: 找 ...