在Python的web框架中编写创建日志的程序的教程


Posted in Python onApril 30, 2015

在Web开发中,后端代码写起来其实是相当容易的。

例如,我们编写一个REST API,用于创建一个Blog:

@api
@post('/api/blogs')
def api_create_blog():
  i = ctx.request.input(name='', summary='', content='')
  name = i.name.strip()
  summary = i.summary.strip()
  content = i.content.strip()
  if not name:
    raise APIValueError('name', 'name cannot be empty.')
  if not summary:
    raise APIValueError('summary', 'summary cannot be empty.')
  if not content:
    raise APIValueError('content', 'content cannot be empty.')
  user = ctx.request.user
  blog = Blog(user_id=user.id, user_name=user.name, name=name, summary=summary, content=content)
  blog.insert()
  return blog

编写后端Python代码不但很简单,而且非常容易测试,上面的API:api_create_blog()本身只是一个普通函数。

Web开发真正困难的地方在于编写前端页面。前端页面需要混合HTML、CSS和JavaScript,如果对这三者没有深入地掌握,编写的前端页面将很快难以维护。

更大的问题在于,前端页面通常是动态页面,也就是说,前端页面往往是由后端代码生成的。

生成前端页面最早的方式是拼接字符串:

s = '<html><head><title>'
 + title
 + '</title></head><body>'
 + body
 + '</body></html>'

显然这种方式完全不具备可维护性。所以有第二种模板方式:

<html>
<head>
  <title>{{ title }}</title>
</head>
<body>
  {{ body }}
</body>
</html>

ASP、JSP、PHP等都是用这种模板方式生成前端页面。

如果在页面上大量使用JavaScript(事实上大部分页面都会),模板方式仍然会导致JavaScript代码与后端代码绑得非常紧密,以至于难以维护。其根本原因在于负责显示的HTML DOM模型与负责数据和交互的JavaScript代码没有分割清楚。

要编写可维护的前端代码绝非易事。和后端结合的MVC模式已经无法满足复杂页面逻辑的需要了,所以,新的MVVM:Model View ViewModel模式应运而生。

MVVM最早由微软提出来,它借鉴了桌面应用程序的MVC思想,在前端页面中,把Model用纯JavaScript对象表示:

<script>
var blog = {
  name: 'hello',
  summary: 'this is summary',
  content: 'this is content...'
};
</script>

View是纯HTML:

<form action="/api/blogs" method="post">
  <input name="name">
  <input name="summary">
  <textarea name="content"></textarea>
  <button type="submit">OK</button>
</form>

由于Model表示数据,View负责显示,两者做到了最大限度的分离。

把Model和View关联起来的就是ViewModel。ViewModel负责把Model的数据同步到View显示出来,还负责把View的修改同步回Model。

ViewModel如何编写?需要用JavaScript编写一个通用的ViewModel,这样,就可以复用整个MVVM模型了。

好消息是已有许多成熟的MVVM框架,例如AngularJS,KnockoutJS等。我们选择Vue这个简单易用的MVVM框架来实现创建Blog的页面templates/manage_blog_edit.html:

{% extends '__base__.html' %}

{% block title %}编辑日志{% endblock %}

{% block beforehead %}

<script>
var
  action = '{{ action }}',
  redirect = '{{ redirect }}';

var vm;

$(function () {
  vm = new Vue({
    el: '#form-blog',
    data: {
      name: '',
      summary: '',
      content: ''
    },
    methods: {
      submit: function (event) {
        event.preventDefault();
        postApi(action, this.$data, function (err, r) {
          if (err) {
            alert(err);
          }
          else {
            alert('保存成功!');
            return location.assign(redirect);
          }
        });
      }
    }
  });
});
</script>
{% endblock %}

{% block content %}
<div class="uk-width-1-1">
  <form id="form-blog" v-on="submit: submit" class="uk-form uk-form-stacked">
    <div class="uk-form-row">
      <div class="uk-form-controls">
        <input v-model="name" class="uk-width-1-1">
      </div>
    </div>
    <div class="uk-form-row">
      <div class="uk-form-controls">
        <textarea v-model="summary" rows="4" class="uk-width-1-1"></textarea>
      </div>
    </div>
    <div class="uk-form-row">
      <div class="uk-form-controls">
        <textarea v-model="content" rows="8" class="uk-width-1-1"></textarea>
      </div>
    </div>
    <div class="uk-form-row">
      <button type="submit" class="uk-button uk-button-primary">保存</button>
    </div>
  </form>
</div>
{% endblock %}

初始化Vue时,我们指定3个参数:

el:根据选择器查找绑定的View,这里是#form-blog,就是id为form-blog的DOM,对应的是一个<form>标签;

data:JavaScript对象表示的Model,我们初始化为{ name: '', summary: '', content: ''};

methods:View可以触发的JavaScript函数,submit就是提交表单时触发的函数。

接下来,我们在<form>标签中,用几个简单的v-model,就可以让Vue把Model和View关联起来:

<!-- input的value和Model的name关联起来了 -->
<input v-model="name" class="uk-width-1-1">

Form表单通过<form v-on="submit: submit">把提交表单的事件关联到submit方法。

需要特别注意的是,在MVVM中,Model和View是双向绑定的。如果我们在Form中修改了文本框的值,可以在Model中立刻拿到新的值。试试在表单中输入文本,然后在Chrome浏览器中打开JavaScript控制台,可以通过vm.name访问单个属性,或者通过vm.$data访问整个Model:

在Python的web框架中编写创建日志的程序的教程

如果我们在JavaScript逻辑中修改了Model,这个修改会立刻反映到View上。试试在JavaScript控制台输入vm.name = 'MVVM简介',可以看到文本框的内容自动被同步了:

在Python的web框架中编写创建日志的程序的教程

双向绑定是MVVM框架最大的作用。借助于MVVM,我们把复杂的显示逻辑交给框架完成。由于后端编写了独立的REST API,所以,前端用AJAX提交表单非常容易,前后端分离得非常彻底。

Python 相关文章推荐
Python判断操作系统类型代码分享
Nov 22 Python
Python 查看文件的编码格式方法
Dec 21 Python
Python使用Scrapy爬虫框架全站爬取图片并保存本地的实现代码
Mar 04 Python
Python Selenium Cookie 绕过验证码实现登录示例代码
Apr 10 Python
Python实现判断给定列表是否有重复元素的方法
Apr 11 Python
python 同时运行多个程序的实例
Jan 07 Python
浅谈python之高阶函数和匿名函数
Mar 21 Python
使用pycharm在本地开发并实时同步到服务器
Aug 02 Python
python 协程中的迭代器,生成器原理及应用实例详解
Oct 28 Python
Pytorch.nn.conv2d 过程验证方式(单,多通道卷积过程)
Jan 03 Python
django使用F方法更新一个对象多个对象字段的实现
Mar 28 Python
Python做图像处理及视频音频文件分离和合成功能
Nov 24 Python
用Python实现web端用户登录和注册功能的教程
Apr 30 #Python
用Python编写web API的教程
Apr 30 #Python
为Python的web框架编写前端模版的教程
Apr 30 #Python
为Python的web框架编写MVC配置来使其运行的教程
Apr 30 #Python
在Python的web框架中配置app的教程
Apr 30 #Python
python实现从ftp服务器下载文件的方法
Apr 30 #Python
简单介绍Python下自己编写web框架的一些要点
Apr 29 #Python
You might like
浅析十款PHP开发框架的对比
2013/07/05 PHP
asp函数split()对应php函数explode()
2019/02/27 PHP
jQuery autocomplete插件修改
2009/04/17 Javascript
javascript 写的一个简单的timer
2009/07/30 Javascript
jquery 模拟雅虎首页的点击对话框效果
2010/04/11 Javascript
让IE6支持min-width和max-width的方法
2010/06/25 Javascript
JQUERY对单选框(radio)操作的小例子
2013/04/25 Javascript
jquery实现表格本地排序的方法
2015/03/11 Javascript
JavaScript获取数组最小值和最大值的方法
2015/06/09 Javascript
实例详解jQuery Mockjax 插件模拟 Ajax 请求
2016/01/12 Javascript
JavaScript+CSS实现的可折叠二级菜单实例
2016/02/29 Javascript
利用js+css+html实现固定table的列头不动
2016/12/08 Javascript
前端主流框架vue学习笔记第二篇
2017/07/26 Javascript
微信小程序 上传头像的实例详解
2017/10/27 Javascript
详解React+Koa实现服务端渲染(SSR)
2018/05/23 Javascript
layUI实现列表查询功能
2019/07/27 Javascript
JavaScript 替换所有匹配内容及正则替换方法
2020/02/12 Javascript
浅谈JavaScript节流和防抖函数
2020/08/25 Javascript
Vue-cli打包后如何本地查看的操作
2020/09/02 Javascript
[00:19]CN DOTA NEVER DIE!VG夺冠rOtK接受采访
2019/12/23 DOTA
[08:38]DOTA2-DPC中国联赛 正赛 VG vs Elephant 选手采访
2021/03/11 DOTA
Python写的服务监控程序实例
2015/01/31 Python
Python中threading模块join函数用法实例分析
2015/06/04 Python
python通过socket查询whois的方法
2015/07/18 Python
Python循环实现n的全排列功能
2019/09/16 Python
解决django接口无法通过ip进行访问的问题
2020/03/27 Python
基于python计算并显示日间、星期客流高峰
2020/05/07 Python
css3 图片圆形显示 如何CSS将正方形图片显示为圆形图片布局
2014/10/10 HTML / CSS
解决H5的a标签的download属性下载service上的文件出现跨域问题
2019/07/16 HTML / CSS
字中字效果的实现【html5实例】
2016/05/03 HTML / CSS
毕业生怎样写好自荐信
2013/11/11 职场文书
心碎乌托邦的创业计划书范文
2013/12/26 职场文书
市场营销毕业生自荐信范文
2014/04/01 职场文书
落实八项规定专题民主生活会对照检查材料
2014/09/15 职场文书
房地产销售助理岗位职责
2015/04/14 职场文书
使用CSS实现按钮边缘跑马灯动画
2023/05/07 HTML / CSS