Flask Web开发实战:深入Jinja2模板引擎与表单处理

桃夭
桃夭
发布时间:2026-10-13 | 2人浏览过
原创

本文详细讲解如何在Flask应用中集成Jinja2模板引擎,通过分离HTML与Python代码提升可维护性。内容涵盖基础路由、POST请求处理、模板变量传递、常用过滤器、控制语句及宏定义,并深入演示模板继承机制,为后续整合Bootstrap前端框架奠定基础。

完成第一章的基础学习后,我们已经能够构建简单的网页。接下来,我们将利用这一方式创建一个登录页面。首先,需要定义一个处理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并提交后,页面将显示登录成功。

虽然功能上实现了预期效果,但从实际应用角度来看,这还远未达到可部署程序的标准。即便暂且不考虑JavaScript脚本和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模板内的代码逻辑与直接写在Python文件中的效果一致,此时刷新页面,显示效果与之前完全相同。虽然视觉效果没有显著改善,但如果后续需要修改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函数支持多参数传递。函数的第一个参数指定模板名称,后续参数为若干键值对,用于向模板变量提供数据。如本例所示,我们将myblog赋值给site_name,而在模板中通过{{参数名}}的语法表示该变量。

此时在浏览器中输入地址,输出结果如下。

<!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 相关产品和应用

全部下载

专题列表