模板
之前已经为应用程序编写了身份验证视图,但是如果正在运行服务器并尝试访问任何 URL,将发生 TemplateNotFound 错误。这是因为视图正在调用 render_template(),但目前尚未编写模板。模板文件将存储在 flaskr 软件包内的 templates 目录中。
模板是包含静态数据以及动态数据占位符的文件。使用特定数据呈现模板以产生最终文档。Flask 使用 Jinja 模板库渲染模板。
在应用程序中,将使用模板呈现将显示在用户浏览器中的 HTML。在 Flask 中,Jinja 被配置为自动转义 HTML 模板中呈现的任何数据。这意味着呈现用户输入是安全的;他们输入的任何可能会扰乱 HTML 的字符,例如 < 和 >,都将转义为安全值,这些转义后的安全值在浏览器中看起来和转义之前相同,但不会引起不必要的效果。
Jinja 类似于 Python。使用特殊的分隔符区分 Jinja 语法和模板中的静态数据。{{ 和 }} 之间的任何内容都是将输出到最终文档的表达式。{% 和 %} 表示类似 if 和 for 的控制流语句。与 Python 不同,代码块由开始和结束标记表示,而不是缩进,因为块中的静态文本可能会更改缩进。
基础布局
应用程序中的每个页面有相同的基础布局。每个模板将扩展一个基础模板并重写特定部分,而不是在每个模板中编写整个 HTML 结构。
flaskr/templates/base.html
<!doctype html>
<title>{% block title %}{% endblock %} - Flaskr</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<nav>
<h1>Flaskr</h1>
<ul>
{% if g.user %}
<li><span>{{ g.user['username'] }}</span>
<li><a href="{{ url_for('auth.logout') }}">Log Out</a>
{% else %}
<li><a href="{{ url_for('auth.register') }}">Register</a>
<li><a href="{{ url_for('auth.login') }}">Log In</a>
{% endif %}
</ul>
</nav>
<section class="content">
<header>
{% block header %}{% endblock %}
</header>
{% for message in get_flashed_messages() %}
<div class="flash">{{ message }}</div>
{% endfor %}
{% block content %}{% endblock %}
</section>
复制
g 在模板中自动可用。根据是否设置了 g.user(通过 load_logged_in_user 设置),显示用户名和注销链接,或显示注册和登录链接。url_for() 也是自动可用的,用于生成视图的 URL,而不是手动写入。
在页面标题之后、内容之前,模板循环遍历 get_flashed_messages() 返回的每条消息。在视图中使用 flash() 来显示错误消息,这是显示错误消息的代码。
此处定义的三个块将在其他模板中被覆盖:
1. {% block title %} 将更改浏览器选项卡中显示的标题和窗口标题。
2. {% block header %} 与 title 类似,但会更改页面上显示的标题。
3. {% block content %} 是每个页面的内容所在,例如登录表单或博客帖子。
基础模板位于 templates 目录中。为了使其他模板保持有序,蓝图的模板将被放置在与蓝图同名的目录中。
注册
flaskr/templates/auth/register.html
{% extends 'base.html' %}
{% block header %}
<h1>{% block title %}Register{% endblock %}</h1>
{% endblock %}
{% block content %}
<form method="post">
<label for="username">Username</label>
<input name="username" id="username" required>
<label for="password">Password</label>
<input type="password" name="password" id="password" required>
<input type="submit" value="Register">
</form>
{% endblock %}
复制
{% extends 'base.html' %} 告知 Jinja 此模板应该替换基础模板中的代码块。所有呈现的内容都必须出现在 {% block %} 标记中,该标记将覆盖基础模板中的代码块。
这里使用一个有用模式,将 {% block title %} 放在 {% block header %} 内。这将设置 title 代码块,然后将其值输出到 header 代码块,以便窗口和页面共享相同的标题,而无需写入两次。
在这里 input 标记使用 required 属性。这会告诉浏览器在填写完这些字段之前不能提交表单。如果用户使用的是不支持该属性的旧浏览器,或者他们使用的是浏览器之外的东西来发出请求,但是我们仍然希望验证 Flask 视图中的数据。在服务器上始终完全验证数据很重要,即使客户端也进行了验证。
登录
除了标题和提交按钮外,与注册模板相同。
flaskr/templates/auth/login.html
{% extends 'base.html' %}
{% block header %}
<h1>{% block title %}Log In{% endblock %}</h1>
{% endblock %}
{% block content %}
<form method="post">
<label for="username">Username</label>
<input name="username" id="username" required>
<label for="password">Password</label>
<input type="password" name="password" id="password" required>
<input type="submit" value="Log In">
</form>
{% endblock %}
复制
注册用户
现在编写了身份验证模板,就可以注册用户了。确保服务器仍在运行(如果没有,则执行 flask run),然后访问 http://127.0.0.1:5000/auth/register。
尝试在不填写表单的情况下单击 “Register” 按钮,查看浏览器是否显示错误消息。尝试从 register.html 模板中删除 required 属性,然后再次单击 “Register”。浏览器不会显示错误,而是会重新加载页面,并显示来自视图中 flash() 的错误。
填写用户名和密码,将被重定向到登录页面。请尝试输入错误的用户名或者密码。如果登录,将会遇到一个错误,因为还没有 index 视图。
原文:
https://flask.palletsprojects.com/en/2.0.x/tutorial/templates/