zoukankan      html  css  js  c++  java
  • 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>
  • 相关阅读:
    Python处理Excel文档(xlrd, xlwt, xlutils)
    张一鸣10年面试过2000人:混得好的年轻人都有这 5 种特质!
    PYTHON对文件及文件夹的一些操作
    ulipad 常用快捷键
    Python之re模块 —— 正则表达式操作
    Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)
    python 深入理解 赋值、引用、拷贝、作用域
    Python 模块学习:re模块
    [置顶] Android资源文件分析
    Tomcat 7最大并发连接数的正确修改方法
  • 原文地址:https://www.cnblogs.com/znyyy/p/11195383.html
Copyright © 2011-2022 走看看