交互101-WEB版日记本软件


需求如下:

  • 通过网页访问系统:
  • 每次运行时合理的打印出过往的所有笔记
  • 一次接收输入一行笔记
  • 在服务端保存为文件
  • 同时兼容 3w 的 Net 版本的命令行界面进行交互

时限: 3wd4~4wd3

  • 发布: 发布到各自仓库的 _src/om2py4w/4wex0/ 目录中
  • 指标:包含软件使用说明书: README.md
  • 能令其它学员根据说明书,运行系统,完成所有功能

备选的:

  • 如果有余力!-)
  • 请尝试: 将消息放到数据库中呢?
  • 哪种数据库?
  • 自制数据库?
  • 内建库支持哪些种类的数据库?

代码仓库

  • https://github.com/jasonycliu/OMOOC2py/tree/master/_src/om2py4w/4wex1

  • 运行说明:

    • 下载目录的内容,在命令行运行python __init__.py python main.py
    • 加入了数据库的支持,所以第一次运行需要初始化表结构, 需要退出的话.直接在命令行按 control + C 就可以退出运行.
    • 程序同时支持web和command line, 在浏览器输入http://localhost:8080可以在web界面记录日记,如需要在common line 下 记录日记则需要再新开一个terminal窗口并运行python client.py

开发过程

根据芝麻星系统的任务分解逐步上周开发的代码接触上添砖加瓦,开发顺序依次是:

  • 使用bottle框架
  • 加入command line支持,使用了urllib在python发送http请求和接收参数
  • 使用bottle 内置的模板返回数据到web页面
  • 尝试在bottle中引入第三方的前端框架bootstrap3,主要涉及到了static_file配置
  • 将日记文件保存在数据库中,使用的是python内置的sqlite3

导入

  • 最小导入包(支持模板,第三方静态文件,db)
      from bottle import route, request, debug, run, jinja2_view, static_file
      import sqlite3
    

核心读写功能

  • 防止中文乱码问题从request请求中获取参数后可以对其进行处理 unicode(diary,'utf-8')
  • 需要用到模板的路由映射中使用@jinja2_view('mydiary.html')加载模板
  • 返回数据到模板使用return {'diarys':mydiary}完成,key值和模板定义的变量保持一致
    #写日记的界面
    @route('/', method='GET')
    @jinja2_view('mydiary.html')
    def log():
        mydiary = read_diary()
    return {'diarys':mydiary}

    #提交日记的POST动作
    @route('/', method='POST')    
    @jinja2_view('mydiary.html')
    def log():
        diary = request.forms.get('diary')
    #防止中文提交不了
    write_diary(unicode(diary,'utf-8'))
    mydiary = read_diary()
    return {'diarys':mydiary}

commad line支持

  • 客户端需要支持command line ,那么在client.py中需要导入相应的包,实际需要在python代码中发送一个http url 请求,以下的包都可以完成

    • urllib
    • urllib2
    • requests
    • subprocess
    • ....
  • 使用urllib的方式向web服务器发起请求,post请求需要构建一个请求参数,同时为了避免乱码问题需要做encode处理,代码如下:

          #common line get请求读取日记信息
          def sync_diary():
              req = urllib.urlopen('http://localhost:8080/read')
              res = req.read()
          print res
    
          #common line post请求写日记
          def post_diary(diary):
              params={}
              params['diary'] = diary
              params = urllib.urlencode(params)
              urllib.urlopen('http://localhost:8080/',params)
          print sync_diary()
    

使用jinja2

  • @jinja2_view("mydiary.html")返回jinja的模板,要使用jinja2是需要安装的

    • 使用easy_install 安装:sudo easy_install Jinja2
    • 使用pip 安装: sudo pip install Jinja2
  • jinja2模板返回从数据库获取的列表数据 结束,并分别取和``````的数据

引入第三方的前端框架

  • 思路: bottle可以为静态文件配置路由的,当模板(HTML)中引入了css,js等静态文件,bottle就会根据配置好的路由去加载这些静态文件. 为了使用bootstrap3 框架,我们可以做以下三步:

    • 模板html文件中后面加上

         <meta charset="utf-8">
         <meta http-equiv="X-UA-Compatible" content="IE=edge">
         <meta name="viewport" content="width=device-width, initial-scale=1">
      
    • 在静态的模板文件中加入bootstrap3所需要的css和js

         <link href="/static/bootstrap.min.css" rel="stylesheet">
         <link href="/static/mydiary.css" rel="stylesheet">
         <script type="text/javascript"src="/static/mydiary.js"></script>
      
    • 在main.py 中加入静态文件的路由映射

         @route('/static/<filename>')
             def server_static(filename):
         return static_file(filename,root='static')
      

将数据保存到db中

  • 选用python 内置的sqlite3,要使用首先需要导入import sqlite3
  • 要记录表中,首先需要做表结构的初始化.
    • 获取sqlite3 数据的连接con = sqlite3.connect('mydiary.db'),没表的话会创建表并获得连接
    • 使用连接conn.execute('创建表sql语句') 创建一个新表
    • 提交conn.commit()

数据库中读写数据

  • 基本原理
    • 获得连接:conn.sqlite3.connect('mydiary.db')
    • 打开游标:conn.cursor()
    • 执行读或写操作:conn.execute('sql')
    • (写)提交:conn.commit()
    • 关闭连接:conn.close()

开发心得(遇到的坑?!!)

  • 写入数据库时没有注意转码,导致写不进数据.对表单数据做unicode处理后解决.
  • 尝试使用bootstrap的时候开始没有想到其实就是在bottle中配置静态文件路由, 通过搜索并看bottle文件后解决. 并且发现搜索的时候很多答案不对,在这里耗了不少时间. 后来觉得两者直接需要整合要么在bootstrap 要么在bottle中会有说明,通过看bootstrap官方按理后发现只是导入静态文件,今儿查看bottle的静态文件导入部分.
  • stackoverflow 有很多前人的经验.
  • 最后还是要多看官方文档和案例,有时候百思不得其解的时候,可能文档有说明.