在Python中使用HTML模版的教程


Posted in Python onApril 29, 2015

Web框架把我们从WSGI中拯救出来了。现在,我们只需要不断地编写函数,带上URL,就可以继续Web App的开发了。

但是,Web App不仅仅是处理逻辑,展示给用户的页面也非常重要。在函数中返回一个包含HTML的字符串,简单的页面还可以,但是,想想新浪首页的6000多行的HTML,你确信能在Python的字符串中正确地写出来么?反正我是做不到。

俗话说得好,不懂前端的Python工程师不是好的产品经理。有Web开发经验的同学都明白,Web App最复杂的部分就在HTML页面。HTML不仅要正确,还要通过CSS美化,再加上复杂的JavaScript脚本来实现各种交互和动画效果。总之,生成HTML页面的难度很大。

由于在Python代码里拼字符串是不现实的,所以,模板技术出现了。

使用模板,我们需要预先准备一个HTML文档,这个HTML文档不是普通的HTML,而是嵌入了一些变量和指令,然后,根据我们传入的数据,替换后,得到最终的HTML,发送给用户:

在Python中使用HTML模版的教程

这就是传说中的MVC:Model-View-Controller,中文名“模型-视图-控制器”。

Python处理URL的函数就是C:Controller,Controller负责业务逻辑,比如检查用户名是否存在,取出用户信息等等;

包含变量{{ name }}的模板就是V:View,View负责显示逻辑,通过简单地替换一些变量,View最终输出的就是用户看到的HTML。

MVC中的Model在哪?Model是用来传给View的,这样View在替换变量的时候,就可以从Model中取出相应的数据。

上面的例子中,Model就是一个dict:

{ 'name': 'Michael' }

只是因为Python支持关键字参数,很多Web框架允许传入关键字参数,然后,在框架内部组装出一个dict作为Model。

现在,我们把上次直接输出字符串作为HTML的例子用高端大气上档次的MVC模式改写一下:

from flask import Flask, request, render_template

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def home():
 return render_template('home.html')

@app.route('/signin', methods=['GET'])
def signin_form():
 return render_template('form.html')

@app.route('/signin', methods=['POST'])
def signin():
 username = request.form['username']
 password = request.form['password']
 if username=='admin' and password=='password':
  return render_template('signin-ok.html', username=username)
 return render_template('form.html', message='Bad username or password', username=username)

if __name__ == '__main__':
 app.run()

Flask通过render_template()函数来实现模板的渲染。和Web框架类似,Python的模板也有很多种。Flask默认支持的模板是jinja2,所以我们先直接安装jinja2:

$ easy_install jinja2

然后,开始编写jinja2模板:

home.html

用来显示首页的模板:

<html>
<head>
 <title>Home</title>
</head>
<body>
 <h1 style="font-style:italic">Home</h1>
</body>
</html>

 
form.html

用来显示登录表单的模板:

<html>
<head>
 <title>Please Sign In</title>
</head>
<body>
 {% if message %}
 <p style="color:red">{{ message }}</p>
 {% endif %}
 <form action="/signin" method="post">
 <legend>Please sign in:</legend>
 <p><input name="username" placeholder="Username" value="{{ username }}"></p>
 <p><input name="password" placeholder="Password" type="password"></p>
 <p><button type="submit">Sign In</button></p>
 </form>
</body>
</html>

signin-ok.html

登录成功的模板:

<html>
<head>
 <title>Welcome, {{ username }}</title>
</head>
<body>
 <p>Welcome, {{ username }}!</p>
</body>
</html>

登录失败的模板呢?我们在form.html中加了一点条件判断,把form.html重用为登录失败的模板。

最后,一定要把模板放到正确的templates目录下,templates和app.py在同级目录下:

在Python中使用HTML模版的教程

启动python app.py,看看使用模板的页面效果:

在Python中使用HTML模版的教程

通过MVC,我们在Python代码中处理M:Model和C:Controller,而V:View是通过模板处理的,这样,我们就成功地把Python代码和HTML代码最大限度地分离了。

使用模板的另一大好处是,模板改起来很方便,而且,改完保存后,刷新浏览器就能看到最新的效果,这对于调试HTML、CSS和JavaScript的前端工程师来说实在是太重要了。

在Jinja2模板中,我们用{{ name }}表示一个需要替换的变量。很多时候,还需要循环、条件判断等指令语句,在Jinja2中,用{% ... %}表示指令。

比如循环输出页码:

{% for i in page_list %}
 <a href="/page/{{ i }}">{{ i }}</a>
{% endfor %}

如果page_list是一个list:[1, 2, 3, 4, 5],上面的模板将输出5个超链接。

除了Jinja2,常见的模板还有:

  •     Mako:用<% ... %>和${xxx}的一个模板;
  •     Cheetah:也是用<% ... %>和${xxx}的一个模板;
  •     Django:Django是一站式框架,内置一个用{% ... %}和{{ xxx }}的模板。

小结

有了MVC,我们就分离了Python代码和HTML代码。HTML代码全部放到模板里,写起来更有效率。

Python 相关文章推荐
python批量提交沙箱问题实例
Oct 08 Python
利用Python演示数型数据结构的教程
Apr 03 Python
对Python3+gdal 读取tiff格式数据的实例讲解
Dec 04 Python
Python 使用folium绘制leaflet地图的实现方法
Jul 05 Python
python实现一个点绕另一个点旋转后的坐标
Dec 04 Python
Python包,__init__.py功能与用法分析
Jan 07 Python
pytorch:model.train和model.eval用法及区别详解
Feb 20 Python
Django中的session用法详解
Mar 09 Python
Numpy中ndim、shape、dtype、astype的用法详解
Jun 14 Python
python 实现两个npy档案合并
Jul 01 Python
python学习笔记之多进程
Aug 06 Python
python3爬虫中多线程的优势总结
Nov 24 Python
以Flask为例讲解Python的框架的使用方法
Apr 29 #Python
详解Python程序与服务器连接的WSGI接口
Apr 29 #Python
Python的SQLAlchemy框架使用入门
Apr 29 #Python
python使用post提交数据到远程url的方法
Apr 29 #Python
python实现根据ip地址反向查找主机名称的方法
Apr 29 #Python
连接Python程序与MySQL的教程
Apr 29 #Python
python实现通过代理服务器访问远程url的方法
Apr 29 #Python
You might like
DIY一个适配电脑声卡的动圈话筒放大器
2021/03/02 无线电
PHP发明人谈MVC和网站设计架构 貌似他不支持php用mvc
2011/06/04 PHP
thinkphp实现like模糊查询实例
2014/10/29 PHP
PHP解析目录路径的3个函数总结
2014/11/18 PHP
浅谈关于PHP解决图片无损压缩的问题
2017/09/01 PHP
PHP删除数组中指定下标的元素方法
2018/02/03 PHP
tp5框架无刷新分页实现方法分析
2019/09/26 PHP
showModalDialog模态对话框的使用详解以及浏览器兼容
2014/01/11 Javascript
基于NodeJS的前后端分离的思考与实践(二)模版探索
2014/09/26 NodeJs
浅谈EasyUI中编辑treegrid的方法
2015/03/01 Javascript
javascript设计模式--策略模式之输入验证
2015/11/27 Javascript
VUEJS实战之利用laypage插件实现分页(3)
2016/06/13 Javascript
jquery 判断div show的状态实例
2016/12/03 Javascript
Vue.js系列之项目搭建(1)
2017/01/03 Javascript
jQuery遍历节点方法汇总(推荐)
2017/05/13 jQuery
如何在vue里添加好看的lottie动画
2018/08/02 Javascript
JavaScript中变量、指针和引用功能与操作示例
2018/08/04 Javascript
vue路由插件之vue-route
2019/06/13 Javascript
[04:10]DOTA2英雄梦之声_第11期_圣堂刺客
2014/06/21 DOTA
[01:29]Ti4循环赛第三日精彩回顾
2014/07/13 DOTA
Python单例模式的两种实现方法
2017/08/14 Python
Python装饰器用法示例小结
2018/02/11 Python
Flask使用Pyecharts在单个页面展示多个图表的方法
2019/08/05 Python
python GUI库图形界面开发之PyQt5表单布局控件QFormLayout详细使用方法与实例
2020/03/06 Python
jupyter notebook oepncv 显示一张图像的实现
2020/04/24 Python
浅谈Python 命令行参数argparse写入图片路径操作
2020/07/12 Python
Python面向对象多态实现原理及代码实例
2020/09/16 Python
使用css3 属性如何丰富图片样式(圆角 阴影 渐变)
2012/11/22 HTML / CSS
什么是类的返射机制
2016/02/06 面试题
编写用C语言实现的求n阶阶乘问题的递归算法
2014/10/21 面试题
数据库方面面试题
2012/04/22 面试题
软件生产职位结构化面试主要考察要素及面试题库
2015/06/12 面试题
管理站站长岗位职责
2013/11/27 职场文书
12月小学生校园广播稿
2014/02/04 职场文书
硕士毕业答辩开场白
2015/05/27 职场文书
党员干部学习三严三实心得体会
2016/01/05 职场文书