02 自定义web框架

自定义web框架

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

如图所示:

 

main.py

 1 # -*- coding: utf-8 -*-
 2 # @Time    : 2019/7/9 20:05
 3 # @Author  : Xiao
 4 
 5 from wsgiref.simple_server import make_server
 6 from urls import url_datas
 7 
 8 def application(environ,start_response):
 9     start_response('200 OK',[('Content-Type','text/html'),('Charset','utf8')])
10     print("PATH", environ.get("PATH_INFO"))
11     # 当前请求路径
12     path = environ.get("PATH_INFO")
13     func = None
14     for item in url_datas:
15         if path == item[0]:
16             func = item[1]
17             break
18     if func:
19         return [func(environ)]
20     return [b'404!']
21 
22 server = make_server('',8080,application)
23 
24 # 开始监听HTTP请求:
25 print('starting....')
26 server.serve_forever()

 

models.py

# -*- coding: utf-8 -*-
# @Time    : 2019/7/16 10:32
# @Author  : Xiao


from tools import Mysql

sql_check_db = "show databases like 'oldboy';"
sql_create_db = 'create database oldboy DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;'
sql_check_table = 'show tables;'
sql_create_table ='create table user_info(id int(10) PRIMARY KEY auto_increment,name VARCHAR(20),password VARCHAR(20),age int(10))'
sql_check_data = 'select count(*) from oldboy'
sql_create_data = "INSERT into user_info(name,password,age) values ('xg','a123456',18),('xk','a123456',38),('xh','a123456',28)"


mysql_check = Mysql('localhost', 3306, 'root', 'root', charset="utf8")

if mysql_check.exec_sql(sql_check_db):
    mysql_create = Mysql('localhost', 3306, 'root', 'root',dbname='oldboy', charset="utf8")
    if mysql_create.exec_sql(sql_check_table):
        if not mysql_create.exec_sql(sql_check_data):
            mysql_create.exec_sql(sql_create_data)
    else:
        mysql_create.exec_sql(sql_create_table)
        mysql_create.exec_sql(sql_create_data)
else:
    mysql_check.exec_sql(sql_create_db)
    mysql_create = Mysql('localhost', 3306, 'root', 'root', dbname='oldboy', charset="utf8")
    mysql_create.exec_sql(sql_create_table)
    mysql_create.exec_sql(sql_create_data)

 

tools.py

# -*- coding: utf-8 -*-
# @Time    : 2019/7/16 10:42
# @Author  : Xiao

import pymysql


class Mysql(object):
    def __init__(self, host, port, user, pwd, dbname="", charset="utf8"):
        """初始化数据库信息以及连接"""
        self.host = host
        self.port = port
        self.user = user
        self.pwd = pwd
        self.dbname = dbname
        self.charset = charset
        self.conn = None  # 给析构函数用的,如果存在链接,则需要关闭链接,没有就不用管
        self.conn = self.get_conn
        self.cur = None
        self.cur = self.get_cur

    @property
    def get_conn(self):
        """根据传参判断是否有传数据库名,然后做不同的链接操作"""
        try:
            if self.dbname:
                conn = pymysql.connect(host=self.host, port=self.port, user=self.user,
                                            password=self.pwd, database=self.dbname, charset=self.charset)
                return conn
            else:
                conn = pymysql.connect(host=self.host, port=self.port, user=self.user,
                                            password=self.pwd, charset=self.charset)
                return conn
        except Exception as e:
            print(e)

    @property
    def get_cur(self):
        """获取游标"""
        if self.conn:
            return self.conn.cursor()

    def exec_sql(self, sql, *args):
        """
        执行sql,根据不同的sql语法做不同的操作:
        查询就返回查询结果列表,其他成功就返回受影响的行数整型,报错返回报错信息字符串
        *args是为了防止sql注入,自己拼接的sql语法字符串可能被sql注入,
        这里的用法是sql不需要自己拼接,直接将变量按顺序传进来,pymysql自动拼接,而且避免了sql注入的问题
        如:
        sql = "insert into test.student VALUES (19,%s,'English',%s);"
        res = test_mysql.exec_sql(sql,"yangxga",100)
        """
        try:
            rows = self.cur.execute(sql, args)  # rows记录受影响的行
            if sql.strip().lower().startswith('select') or sql.strip().lower().startswith('show'):
                res = self.cur.fetchall()
                res = self.format_res(res)
                print(res)
                return res
            else:
                self.conn.commit()  # 非查询语句需要提交才能生效
                res = rows
                print(res)
                return res
        except Exception as e:
            print(e)
            return e

    @staticmethod
    def format_res(res):
        """格式化数据库查找到的结果,如果"""
        res_lis = []
        if res:
            for i in res:
                res_lis.append(i)
        return res_lis

    def __del__(self):
        """析构函数,关闭鼠标,断开连接"""
        if self.cur:
            self.cur.close()
        if self.conn:
            self.conn.close()

 

urls.py

# -*- coding: utf-8 -*-
# @Time    : 2019/7/9 20:05
# @Author  : Xiao

from views import *

url_datas = [
    ('/favicon.ico',favicon),
    ('/index',index),
    ('/login',login),
    ('/regist',regist)
]

 

views.py

# -*- coding: utf-8 -*-
# @Time    : 2019/7/9 20:17
# @Author  : Xiao


from tools import Mysql
from urllib.parse import parse_qs

def op_file(filename):
    with open(filename,'rb') as f:
        data = f.read()
    return data

def favicon(environ):
    data = op_file('./templates/favicon.ico')
    return data

def index(environ):
    data = op_file('./templates/index.html')
    return data

def regist(environ):
    method = environ.get('REQUEST_METHOD').lower()
    if method == 'post':
        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')
        if user.strip() and pwd.strip():
            mysql_check = Mysql('localhost', 3306, 'root', 'root',dbname='oldboy', charset="utf8")
            sql = "select * from user_info WHERE  name=%s"
            res = mysql_check.exec_sql(sql, user, pwd)
            if res and isinstance(res, list):
                data = b'username is already exits!'
            else:
                data = op_file('./templates/index.html')
                sql_reg = "insert into user_info(name,password) values(%s,%s);"
                mysql_check.exec_sql(sql_reg,user,pwd)
        else:
            data = b'username and password can not be empty!'
    else:
        data = op_file('./templates/register.html')
    return data

def login(environ):
    method = environ.get('REQUEST_METHOD').lower()
    if method == 'post':
        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')
        mysql_check = Mysql('localhost', 3306, 'root', 'root', dbname='oldboy', charset="utf8")
        sql = "select * from user_info WHERE  name=%s and password=%s"
        res = mysql_check.exec_sql(sql, user, pwd)
        if res and isinstance(res,list):
            data = op_file('./templates/index.html')
        else:
            data = b'username or password is wrong!'
    else:
        data = op_file('./templates/login.html')
    return data

 

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
    <style type="text/css">
        h3{
            margin: 10px 12px;
            float: left;
            overflow: hidden;
        }
        button{
            margin: 12px;
            overflow: hidden;
        }
    </style>
</head>
<body>
<h3>欢迎进入首页</h3>
<button id="btn_reg">注册</button>
<button id="btn_login">登陆</button>
<form action="">
    <img src="http://pic39.nipic.com/20140321/18063302_210604412116_2.jpg">
</form>
</body>
<script type="text/javascript">
    window.onload = function () {
        var tmp_reg = document.getElementById('btn_reg');
        var tmp_login = document.getElementById('btn_login');
        tmp_reg.onclick = function () {
            window.open('http://127.0.0.1:8080/regist',target='_self')
        }
        tmp_login.onclick = function () {
            window.open('http://127.0.0.1:8080/login',target='_self')
        }
    }
</script>
</html>

 

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登录</title>
</head>
<body>
<h3>登录</h3>
<form action="http://127.0.0.1:8080/login" method="post">
    <label for="user">用户名:</label>
    <input type="text" name="user" id="user">
    <label for="pwd">密码:</label>
    <input type="password" name="pwd" id="pwd">
    <input type="submit" value="登录">
</form>
</body>
</html>

 

register.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册</title>
</head>
<body>
<h3>注册</h3>
<form action="http://127.0.0.1:8080/regist" method="post">
    <label for="user">用户名:</label>
    <input type="text" name="user" id="user">
    <label for="pwd">密码:</label>
    <input type="password" name="pwd" id="pwd">
    <input type="submit" value="注册">
</form>
</body>
</html>

 

posted @ 2019-07-16 15:52  毛斯钢  阅读(200)  评论(0编辑  收藏  举报