一个基于flask的web应用诞生 使用模板引擎和表单插件(2)


Posted in Python onApril 11, 2017

经过了第一章的内容,已经可以做出一些简单的页面,首先用这种方式做一个登录页面,首先要创建一个login的路由方法:

@app.route("/login",methods=["GET"])
def login():
 html="<form method='post'>" \
 "<table>" \
 "<tr><td>请输入用户名</td><td><input type='text' name='username'/></td></tr>" \
 "<tr><td>请输入密码</td><td><input type='password' name='password'/></td></tr>" \
 "<tr><td><input type='submit' value='登录'/></td></tr>" \
 "</table>" \
 "</post>"
 return html

这个页面返回后是一个简单的登录页,显示结果如下:

一个基于flask的web应用诞生 使用模板引擎和表单插件(2)

然后是一个登录的post返回页:

@app.route("/login",methods=["POST"])
def loginPost():
 username=request.form.get("username","")
 password=request.form.get("password","")
 if username=="test" and password=="123" :
 return "登录成功"
 else:
 return "登录失败"

输入test和123后,显示登录成功

一个基于flask的web应用诞生 使用模板引擎和表单插件(2)

功能上当然是实现了,但是从其他方面来说,却很难说它是一个能够实际应用的程序,即使不考虑js脚本和css样式表,就从简简单单的维护来说,就是一场噩梦,比如说像增加一个验证码框,我想不会有人认为这是一件愉快的工作。

所以,首先来说,我们要把页面html部分独立出来,这点,flask提供了jinja2模板引擎来实现。

jinja2模板引擎同样符合flask最基础的约定,即众多配置中都有一个基础的默认值,相对jinja2来说,有一个最重要的默认值,即模板文件放在templates文件夹,这个文件夹虽然可以自定义,但目前来说,使用默认值已经足够了。

好,首先在PyCharm的项目根目录创建templates文件夹,然后在文件夹内创建login.html文件,当然目录结构如下:

一个基于flask的web应用诞生 使用模板引擎和表单插件(2)

在login.html中输入代码如下:

<!DOCTYPE html>
<html>
 <head>
 <title>欢迎您登陆--牛博客</title>
 </head>
 <body>
 <form method='post'>
 <table>
 <tr><td>请输入用户名</td><td><input type='text' name='username'/></td></tr>
 <tr><td>请输入密码</td><td><input type='password' name='password'/></td></tr>
 <tr><td><input type='submit' value='登录'/></td></tr>
 </table>
 </form>
 </body>
</html>

代码很简单,也名没有进行样式方面的美化,其实目前就我来说,仅仅是因为有了智能感知,就有足够的理由使用模板了,然后,对default.py的login方法进行修改代码为:

from flask import render_template #头部,引入模板渲染方法

@app.route("/login",methods=["GET"])
def login():
 return render_template("/login.html") 

 #渲染模板,默认找templates文件夹下的login.html文件

由于html模板内的代码和直接直接写在py文件中的一样,所以此时刷新页面,显示效果和刚刚相同,虽然显示效果没有明显的改观,但此时如果修改html中的某一元素,则会方便很多。

关于jinja2模板引擎还支持一些更强大的功能,比如使用index做一些说明:

基本用法

修改default.py中的部分代码为:

from flask import render_template #页头,导入渲染函数

@app.route("/")
def index():
 return render_template("index.html",site_name='myblog')

index.html中的代码为:

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>{{site_name}}</title>
</head>
<body>
<h1>这个站点的名字为 {{site_name}} </h1>
</body>
</html>

flask的render_template函数支持多参数,其中函数的第一个参数为模板名,之后可以提供若干参数,均为键值对,为模板中的变量提供数据。如此例子中,为site_name提供了myblog的值,而模板内使用{{参数名}}来表示一个变量

此时浏览器输入地址输出结果为:

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>myblog</title>
</head>
<body>
<h1>这个站点的名字为 myblog </h1>
</body>
</html>

jinja2模板还提供了一些变量过滤器,如代码:

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>{{site_name|upper}}</title>
</head>
<body>
<h1>这个站点的名字为 {{site_name}} </h1>
</body>
</html>

这时输出为:

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>MYBLOG</title>
</head>
<body>
<h1>这个站点的名字为 myblog </h1>
</body>
</html>

常用过滤器如下

safe 不转义
capitalize 首字母大写
lower 转换为小写
upper 转换为大写
trim 去收尾空格
striptages 去除html标签

除此之外,Jinja2的变量还可以是一些复杂类型,甚至可以使用一些复杂类型的常用方法,如:

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>{{site_name[2:]}}</title> 
</head>
<body>
<h1>这个站点的名字为 {{site_name}} </h1>
</body>
</html>

这时输出为:

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>blog</title>
</head>
<body>
<h1>这个站点的名字为 myblog </h1>
</body>
</html>

控制语句

控制语句是一个模板的基本功能,同样的jinja2也提供了相应的功能:

//选择
{% if name=='test' %}
 这是测试
{% else %}
 {{name}},你好
{% endif %}

//循环
<ul>
 {% for blog in blogs%}
 {{ blog.title }}
 {% endfor%}
</ul>

除了这些基本用法,模板还为一些代码的重复使用提供了宏的功能,如将如下代码写入macros.html文件中

{% macro render_title(blog)%}
 <li>{{blog.title}}</li>
{% endmacro%}

然后在之前的模板中:

{% import 'macros.html' as macros %}
<ul>
 {% for blog in blogs %}
 {{ macros.render_title(blog) }}
 {% endfor %}
</ul>

执行结果与之前的完全相同

Jinja2还提供了一个更为强大的功能,即模板继承,这个个人感觉有点像java的sitemesh框架,它首先需要创建一个base.html的基模板:

<!DOCTYPE html>
<html>
<head>
 {% block head %}
 <meta charset="UTF-8">
 <title>{% block title%} {% endblock %} - 牛博客</title>
 <script src="http://cdn.bootcss.com/jquery/2.2.4/jquery.min.js"></script>
 {% endblock %}
</head>
<body>
 {% block body %}
 {% endblock %}
</body>
</html>

其中block标签的意思表示在子模板中可以修改,具体到此例子,则可修改的部分为 head,title,body。下面为子模板代码:

{% extends "base.html" %}
{% block title %}{{site_name[2:]}}{% endblock %}
{% block head %}
 {{super()}}
{% endblock %}

{% block body %}
 <h1>这个站点的名字为 {{site_name}} </h1>
{% endblock %}

此时执行结果仍为:

<!DOCTYPE html>
<html>
<head>
 <meta charset="UTF-8">
 <title>blog</title>
</head>
<body>
<h1>这个站点的名字为 myblog </h1>
</body>
</html>

现在有了模板引擎,不管怎么说,仅仅就页面层来说,已经可以很轻松的做出一些不错的功能了,但很明显,现在的界面还不是很美观,下一章将把现在主流的前端框架bootstrap与flask框架进行整合。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
利用Python演示数型数据结构的教程
Apr 03 Python
使用Python编写类UNIX系统的命令行工具的教程
Apr 15 Python
Python编程之基于概率论的分类方法:朴素贝叶斯
Nov 11 Python
利用信号如何监控Django模型对象字段值的变化详解
Nov 27 Python
详谈python3 numpy-loadtxt的编码问题
Apr 29 Python
python矩阵转换为一维数组的实例
Jun 05 Python
Python如何发布程序的详细教程
Oct 09 Python
python之消除前缀重命名的方法
Oct 21 Python
Python设计模式之建造者模式实例详解
Jan 17 Python
Python 日期区间处理 (本周本月上周上月...)
Aug 08 Python
python能在浏览器能运行吗
Jun 17 Python
对Python 字典元素进行删除的方法
Jul 31 Python
非递归的输出1-N的全排列实例(推荐)
Apr 11 #Python
一个基于flask的web应用诞生(1)
Apr 11 #Python
Python 文件处理注意事项总结
Apr 10 #Python
python非递归全排列实现方法
Apr 10 #Python
python 生成器生成杨辉三角的方法(必看)
Apr 10 #Python
Python贪吃蛇游戏编写代码
Oct 26 #Python
OpenCV实现人脸识别
Apr 07 #Python
You might like
使用sockets:从新闻组中获取文章(三)
2006/10/09 PHP
PHP 分页原理分析,大家可以看看
2009/12/21 PHP
PHP的可变变量名的使用方法分享
2012/02/05 PHP
分享常见的几种页面静态化的方法
2015/01/08 PHP
基于php流程控制语句和循环控制语句(讲解)
2017/10/23 PHP
PHP实现对数字分隔加千分号的方法
2019/03/18 PHP
javascript 二维数组的实现与应用
2010/03/16 Javascript
网页前台通过js非法字符过滤代码(骂人的话等等)
2010/05/26 Javascript
ie6下png图片背景不透明的解决办法使用js实现
2013/01/11 Javascript
js工具方法弹出蒙版
2013/05/08 Javascript
js返回前一页刷新本页重载页面
2014/07/29 Javascript
JavaScript实现按照指定长度为数字前面补零输出的方法
2015/03/19 Javascript
原生js实现addClass,removeClass,hasClass方法
2016/04/27 Javascript
基于SpringMVC+Bootstrap+DataTables实现表格服务端分页、模糊查询
2016/10/30 Javascript
JavaScript模板引擎Template.js使用详解
2016/12/15 Javascript
Bootstrap输入框组件简单实现代码
2017/03/06 Javascript
JavaScript函数表达式详解及实例
2017/05/05 Javascript
vue自定义全局组件(自定义插件)的用法
2018/01/30 Javascript
微信小程序背景音乐开发详解
2019/12/12 Javascript
vue-cli设置publicPath小记
2020/04/14 Javascript
如何在node环境实现“get数据解析”代码实例
2020/07/03 Javascript
JavaScript实现筛选数组
2021/03/02 Javascript
利用Python开发微信支付的注意事项
2016/08/19 Python
python表格存取的方法
2018/03/07 Python
python+pyqt5实现图片批量缩放工具
2019/03/18 Python
python利用selenium进行浏览器爬虫
2019/04/25 Python
python不相等的两个字符串的 if 条件判断为True详解
2020/03/12 Python
Python 字节流,字符串,十六进制相互转换实例(binascii,bytes)
2020/05/11 Python
CSS3实例分享--超炫checkbox复选框和radio单选框
2014/09/01 HTML / CSS
使用html5 canvas创建太空游戏的示例
2014/05/08 HTML / CSS
Expedia印度尼西亚站:预订酒店、廉价航班和度假套餐
2018/01/31 全球购物
世嘉游戏英国官方商店:SEGA Shop UK
2019/09/20 全球购物
JACK & JONES荷兰官网:男士服装和鞋子
2021/03/07 全球购物
List、Map、Set三个接口,存取元素时,各有什么特点?
2015/09/27 面试题
小学毕业典礼演讲稿
2014/09/09 职场文书
专题组织生活会发言材料
2014/10/17 职场文书