经过了第一章的内容,已经可以做出一些简单的页面,首先用这种方式做一个登录页面,首先要创建一个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

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

然后是一个登录的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后,显示登录成功

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

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

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

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

在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框架进行整合。

一个web应用的诞生(2)--使用模板的更多相关文章

  1. 一个web应用的诞生--使用模板

    经过了第一章的内容,已经可以做出一些简单的页面,首先用这种方式做一个登录页面,首先要创建一个login的路由方法: @app.route("/login",methods=[&qu ...

  2. 一个web应用的诞生(1)--初识flask

    基于flask的web应用的诞生 Flask是一个非常优秀的web框架,它最大的特点就是保持一个简单而易于扩展的小核心,其他的都有用户自己掌握,并且方便替换,甚至,你可以在社区看到众多开源的,可直接用 ...

  3. 一个web应用的诞生--美化一下

    经过上一章的内容,其实就页面层来说已结可以很轻松的实现功能了,但是很明显美观上还有很大的欠缺,现在有一些很好的前端css框架,如AmazeUI,腾讯的WeUI等等,这里推荐一个和flask集成很好的b ...

  4. 一个web应用的诞生--数据表单

    下面把角色分为两种,普通用户和管理员用户,至少对于普通用户来说,直接修改DB是不可取的,要有用户注册的功能,下面就开始进行用户注册的开发. 用户表 首先要想好用户注册的时候需要提供什么信息:用户名.密 ...

  5. 一个web应用的诞生(6)--用户账户

    之前登录注册的功能都已经完成,但是登录成功回到首页发现还是白茫茫的一片,对的,title一直都写得博客,那么最终目的也是写出一个轻博客来,但是,在发表文章之前是不是要先记录一下登录状态呢? 用户登录 ...

  6. 一个web应用的诞生(8)--博文发布

    这个系统一直号称轻博客,但貌似博客的功能还没有实现,这一章将简单的实现一个博客功能,首先,当然是为数据库创建一个博文表(models\post.py): from .. import db from ...

  7. 一个web应用的诞生(9)--回到用户

    在开始之前,我们首先根据之前的内容想象一个场景,用户张三在网上浏览,看到了这个轻博客,发现了感兴趣的内容,于是想要为大家分享一下心情,恩?发现需要注册,好,输入用户名,密码,邮箱,并上传头像后,就可以 ...

  8. 一个web应用的诞生(10)--关注好友

    下面回到首页中,使用一个账户登录,你肯定已经注意到了这里的内容: 没错,现在都是写死的一些固定信息,其中分享数量很容易就可以获取,只需要修改首页模板: <p class="text-m ...

  9. 一个web应用的诞生(11)--列表分页

    上章的结束,若在实际开发过程中,会发现一个问题,那就首页或关注分享,是一下子按时间顺序全部显示出来,这在实际项目中不可能出现的,想想实际中的产品是如何做的? 一般来说,无非是两种,一种是使用页码,来进 ...

随机推荐

  1. Semtech 的 137-1050 MHz 超低功耗长距离收发器(SX1276 Long Range Transceiver)

    SX1276 收发器采用 LoRa? 长距离调制解调器,可实现超长距离扩频通信和高抗干扰能力,并将电流消耗降至最低.凭借 Semtech 专利的 LoRa 调制技术,SX1276 使用低成本晶体和物料 ...

  2. Xcode 错误收集及解决办法

    1.An unknown error occurred. 如果仅仅提示“An unknown error occurred.” 而没有别的提示,很有可能是设备内存已满,没有足够的空间来安装这个应用. ...

  3. nRF5 SDK for Mesh(六) BLE MESH 的 基础概念

    Basic Bluetooth Mesh concepts The Bluetooth Mesh is a profile specification developed and published ...

  4. Token生成(转载)

    package main import ( "encoding/base64" "encoding/json" "log" "ne ...

  5. ora.ctssd OBSERVER

    [grid@ydb1 ~]$ crsctl status res -t -init    ora.ctssd      1        ONLINE  ONLINE       ydb1       ...

  6. pl/sql下载

    详解Oracle客户端工具:PL/SQL工具下载: 下载地址:http://www.oraclejsq.com/article/010100114.html

  7. MAC 相关

    1.找回个人收藏下的消失项,如文稿等   点击个人收藏中下的任意项,如桌面.下载等,按住Command+上箭头,出现如下界面,拖住消失项添加到个人收藏即可

  8. iOS之Custom UIViewController Transition

    本文学习下自定义ViewController的切换,从无交互的到交互式切换. (本文已同步到我的小站:icocoa,欢迎访问.) iOS7中定义了3个协议: UIViewControllerTrans ...

  9. Java监听器原理及实例

    一.监听器原理 监听器是基于事件驱动的,用于对操作事件进行监听.处理,是观察者设计模式的应用 监听器三元素: 2.1 事件源:事件发生的源头 2.2 事件:对事件进行抽象.封装 2.3 监听器:用于监 ...

  10. navicat mysql 存储过程

    存储过程如同一门程序设计语言,同样包含了数据类型.流程控制.输入和输出和它自己的函数库. 一.基本数据类型:略 二.变量: 自定义变量:DECLARE   a INT ; SET a=100; 可用以 ...