8:mini-web框架2:添加路由和MySQL功能

一、用装饰器完成路由功能

1.1、用装饰器完成路由功能1

import re

def index():

    with open("./templates/index.html") as f:

        content = f.read()

    my_stock_info = "测试一下,数据"

    content = re.sub(r"\{%content%\}",my_stock_info,content)

    return content

def center():

    with open("./templates/center.html") as f:

      content = f.read()

    my_stock_info = "这是从数据库查询出来的数据"

    content = re.sub(r"\{%content%\}",my_stock_info,content)

    return content

URL_FUNC_DICT = {

  "/index.py":index,

  "/center.py":center

}

def application(evn,start_reponse):


      start_reponse('200 OK',[('Content-Type','text/html;charset=utf-8')])

      file_name = evn['PATH_INFO']

      func = URL_FUNC_DICT[file_name]

      return func()

提示:主要是URL_FUNC_DICT 字典的引入,不用再像以前那样的判断 file_name 是否存在了,如下

缺点:URL_FUNC_DICT字典还需要手动配置,以及file_name不存在的时候会出现问题,下面我们看 2 的优化

1.2、用装饰器完成路由功能2

目的:去掉1.1中的代码

优化方式,使用带参数的装饰器来实现 URL_FUNC_DICT 来自动添加元素,代码如下

完整的代码如下

import re

# 定义一个空子典

URL_FUNC_DICT = dict()

# 用来存放url路由映射

def route(url):

      """

      带参数的装饰器来做路由

      :param url: 请求的url

      :return: 返回一个装饰器

      """

      def set_func(func):

          # 添加键值对,key是需要访问的url,value是当这个url需要访问的时候,需要调用的函数引用

          URL_FUNC_DICT[url] = func

          def call_func(*args, **kwargs):

              return func(*args, **kwargs)

          return call_func

      return set_func

@route("/index.py")

def index():

      with open("./templates/index.html") as f:

            content = f.read()

      my_stock_info = "测试一下,数据"

      content = re.sub(r"\{%content%\}", my_stock_info, content)

      return content

@route("/center.py")

def center():

      with open("./templates/center.html") as f:

            content = f.read()

      my_stock_info = "这是从数据库查询出来的数据"

      content = re.sub(r"\{%content%\}", my_stock_info, content)

      return content

def application(evn, start_reponse):

      start_reponse('200 OK', [('Content-Type', 'text/html;charset=utf-8')])

      file_name = evn['PATH_INFO']

      func = URL_FUNC_DICT[file_name]

      return func()

1.3、用装饰器完成路由功能3:解决 字典URL_FUNC_DICT里面不存在键值对的情况

方式一:使用 key in dict,也就是判断一个键在字典中是否在存在,如下

方式二:使用 try

对比两种方式的选择哪一个更好

使用try还是比较好的,因为它具有异常转发的功能,而方式一没有

1.4、简单的解释一下路由route

路由route:路由的功能是数据的转发,上面使用到路由的功能是字典的映射

二、伪静态、静态和动态的区别

目前开发的网站其实真正意义上都是动态网站,只是URL上有些区别,一般URL分为静态URL、动态URL、伪静态URL,他们的区别是什么?

2.1、静态URL

静态URL类似域名/news/hh/login.html我们一般称为真静态URL,每个网页有真实的物理路径,也就是真实存在服务器里的。

优点是:网站打开速度快,因为它不用进行运算;另外网址结构比较友好,利于记忆。

缺点是:最大的缺点是如果是中大型网站,则产生的页面特别多,不好管理。至于有的开发者说占用硬盘空间大,我觉得这个可有忽略不计,占用不了多少空间的,况且目前硬盘空间都比较大。还有的开发者说会伤硬盘,这点也可以忽略不计。

一句话总结:静态网站对SEO的影响:静态URL对SEO肯定有加分的影响,因为打开速度快,这个是本质。

2.2、动态URL

动态URL类似域名/NewsMore.asp?id=5 或者 域名/DaiKuan.php?id=17,带有?号的URL,我们一般称为动态网址,每个URL只是一个逻辑地址,并不是真实物理存在服务器硬盘里的。

优点是:适合中大型网站,修改页面很方便,因为是逻辑地址,所以占用硬盘空间要比纯静态网站小。

缺点是:因为要进行运算,所以打开速度稍慢,不过这个可有忽略不计,目前有服务器缓存技术可以解决速度问题。最大的缺点是URL结构稍稍复杂,不利于记忆。

一句话总结:动态URL对SEO的影响:目前百度SE已经能够很好的理解动态URL,所以对SEO没有什么减分的影响(特别复杂的URL结构除外)。所以你无论选择动态还是静态其实都无所谓,看你选择的程序和需求了。

2.3、伪静态URL

伪静态URL类似域名/course/2.html这个URL和真静态URL类似。他是通过伪静态规则把动态URL伪装成静态网址。也是逻辑地址,不存在物理地址。

优点是:URL比较友好,利于记忆。非常适合大中型网站,是个折中方案。

缺点是:设置麻烦,服务器要支持重写规则,小企业网站或者玩不好的就不要折腾了。另外进行了伪静态网站访问速度并没有变快,因为实质上它会额外的进行运算解释,反正增加了服务器负担,速度反而变慢,不过现在的服务器都很强大,这种影响也可以忽略不计。还有可能会造成动态URL和静态URL都被搜索引擎收录,不过可以用robots禁止掉动态地址。

一句话总结:使用的时候和动态URL一样,但是伪静态对SEO没有什么减分影响。

三、mini_frame框架添加MySQL功能

3.1、进入mysql

mysql -u 用户名 -p密码

3.2、创建数据库 stock_db以及表和数据stock_db.sql文件

<1>、创建数据库 stock_db以及使用

# 创建数据库 `stock_db `

create database stock_db charset=utf8;

# 使用数据库 `stock_db `

use stock_db;

<2>、导入数据(在练习的时候需要这个文件的可以找我要)

source stock_db.sql;

提示:stock_db.sql是一个 sql文件,里面是一些表创建以及数据导入的代码,在执行上面的代码的是一定要在 stock_db.sql文件同一个路径

<3>、focus与info 的表结构如下

3.3、mysql数据库查询的正式使用,效果如下:

def index():里面的代码如下

def index():

      with open("./templates/index.html") as f:

            content = f.read()

      # my_stock_info = "测试一下,数据"

      # 创建Connection连接

      conn = connect(host='ironman.ren', port=3306, database='stock_db', user='账号名', password='密码', charset='utf8')

      # 获得Cursor对象

      cursor = conn.cursor()

      cursor.execute("select * from info;")

      stock_infos = cursor.fetchall()

      cursor.close()

      conn.close()

      tr_template = """<tr>

          <td>%s</td>

          <td>%s</td>

          <td>%s</td>

          <td>%s</td>

          <td>%s</td>

          <td>%s</td>

          <td>%s</td>

          <td>%s</td>

          <td>

            <input type="button" value="添加" id="toAdd" name="toAdd" systemidvalue="000007">

          </td>

        </tr>

      """

    html = ""

    for line_info in stock_infos:

        html += tr_template%(line_info[0],line_info[1],line_info[2],line_info[3],line_info[4],line_info[5],line_info[6],line_info[7])

    content = re.sub(r"\{%content%\}", str(html), content)

    return content

def center():里面的效果与代码如下

def center():

      with open("./templates/center.html") as f:

            content = f.read()

      # 创建Connection连接

      conn = connect(host='ironman.ren', port=3306, database='stock_db', user='账号名', password='密码',

            charset='utf8')

      # 获得Cursor对象

      cursor = conn.cursor()

      cursor.execute("select i.code,i.short,i.chg,i.turnover,i.price,i.highs,f.note_info from info as i inner join focus as f on i.id = f.info_id;")

      stock_infos = cursor.fetchall()

      cursor.close()

      conn.close()

      tr_template = """<tr>

        <td>%s</td>

        <td>%s</td>

        <td>%s</td>

        <td>%s</td>

        <td>%s</td>

        <td>%s</td>

        <td>%s</td>

        <td>

            <a type="button" class="btn btn-default btn-xs" href="/update/300268.html"> <span class="glyphicon glyphicon-star" aria-hidden="true"></span> 修改 </a>

        </td>

        <td>

            <input type="button" value="删除" id="toDel" name="toDel" systemidvalue="300268">

        </td>

      </tr>

      """

      html = ""

      for line_info in stock_infos:

          html += tr_template % (line_info[0], line_info[1], line_info[2], line_info[3], line_info[4], line_info[5], line_info[6])

      content = re.sub(r"\{%content%\}", str(html), content)

      return content

上述两个代码最主要的理解查询数据后再拼接,返回一个content

补充:

面向切面:装饰器添加功能,让原本的框架去调用,不用管其他的,只需要写自己函数内的代码


作者:IIronMan

链接:https://www.jianshu.com/p/884850411919

来源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容