【一周掌握Flask框架学习笔记】Template模板Html页面编写

2021-08-11 16:17:04 浏览数 (1)

Jinja2模板引擎

模板

在前面的示例中,视图函数的主要作用是生成请求的响应,这是最简单的请求。实际上,视图函数有两个作用:处理业务逻辑和返回响应内容。在大型应用中,把业务逻辑和表现内容放在一起,会增加代码的复杂度和维护成本。本节学到的模板,它的作用即是承担视图函数的另一个作用,即返回响应内容。

  • 模板其实是一个包含响应文本的文件,其中用占位符(变量)表示动态部分,告诉模板引擎其具体的值需要从使用的数据中获取
  • 使用真实值替换变量,再返回最终得到的字符串,这个过程称为“渲染”
  • Flask是使用 Jinja2 这个模板引擎来渲染模板

使用模板的好处:

  • 视图函数只负责业务逻辑和数据处理(业务逻辑方面)
  • 而模板则取到视图函数的数据结果进行展示(视图展示方面)
  • 代码结构清晰,耦合度低

Jinja2

两个概念

Jinja2:是 Python 下一个被广泛应用的模板引擎,是由Python实现的模板语言,他的设计思想来源于 Django 的模板引擎,并扩展了其语法和一系列强大的功能,其是Flask内置的模板语言。 模板语言:是一种被设计来自动生成文档的简单文本格式,在模板语言中,一般都会把一些变量传给模板,替换模板的特定位置上预先定义好的占位变量名。

渲染模版函数

Flask提供的 render_template 函数封装了该模板引擎 render_template 函数的第一个参数是模板的文件名,后面的参数都是键值对,表示模板中变量对应的真实值。

使用
注释

使用 {# #} 进行注释

代码语言:javascript复制
{# 这是注释 #}
变量代码块

{{}} 来表示变量名,这种 {{}} 语法叫做变量代码块 {{ post.title }} Jinja2 模版中的变量代码块可以是任意Python类型或者对象,只要它能够被Python的str()方法转换为一个字符串就可以,比如,可以通过下面的方式显示一个字典或者列表中的某个元素:

代码语言:javascript复制
{{your_dict['key']}}
{{your_list[0]}}
控制代码块

用 {%%} 定义的控制代码块,可以实现一些语言层次的功能,比如循环或者if语句

代码语言:javascript复制
{% if user %}
    {{ user }}
{% else %}
    hello!
    
{% for index in indexs %}
    {{ index }} 
{% endfor %}

过滤器

过滤器的本质就是函数。有时候我们不仅仅只是需要输出变量的值,我们还需要修改变量的显示,甚至格式化、运算等等,而在模板中是不能直接调用 Python 中的某些方法,那么这就用到了过滤器。

使用方式:

过滤器的使用方式为:变量名 | 过滤器。

代码语言:javascript复制
{{variable | filter_name(*args)}}

如果没有任何参数传给过滤器,则可以把括号省略掉

代码语言:javascript复制
{{variable | filter_name}}

如:``,这个过滤器的作用:把变量variable 的值的首字母转换为大写,其他字母转换为小写

链式调用

在 jinja2 中,过滤器是可以支持链式调用的,示例如下:

代码语言:javascript复制
{{ "hello world" | reverse | upper }}

常见内建过滤器

字符串操作

  • safe:禁用转义
代码语言:javascript复制
<p>{{ '<em>hello</em>' | safe }}</p>
  • capitalize:把变量值的首字母转成大写,其余字母转小写
代码语言:javascript复制
<p>{{ 'hello' | capitalize }}</p>
  • lower:把值转成小写
代码语言:javascript复制
<p>{{ 'HELLO' | lower }}</p>
  • upper:把值转成大写
代码语言:javascript复制
<p>{{ 'hello' | upper }}</p>
  • title:把值中的每个单词的首字母都转成大写
代码语言:javascript复制
<p>{{ 'hello' | title }}</p>
  • reverse:字符串反转
代码语言:javascript复制
<p>{{ 'olleh' | reverse }}</p>
  • format:格式化输出
代码语言:javascript复制
<p>{{ '%s is %d' | format('name',17) }}</p>
  • striptags:渲染之前把值中所有的HTML标签都删掉
代码语言:javascript复制
<p>{{ '<em>hello</em>' | striptags }}</p>
  • truncate: 字符串截断
代码语言:javascript复制
<p>{{ 'hello every one' | truncate(9)}}</p>

列表操作

  • first:取第一个元素
代码语言:javascript复制
<p>{{ [1,2,3,4,5,6] | first }}</p>
  • last:取最后一个元素
代码语言:javascript复制
<p>{{ [1,2,3,4,5,6] | last }}</p>
  • length:获取列表长度
代码语言:javascript复制
<p>{{ [1,2,3,4,5,6] | length }}</p>
  • sum:列表求和
代码语言:javascript复制
<p>{{ [1,2,3,4,5,6] | sum }}</p>
  • sort:列表排序
代码语言:javascript复制
<p>{{ [6,2,3,1,5,4] | sort }}</p>

语句块过滤

代码语言:javascript复制
{% filter upper %}
    一大堆文字
{% endfilter %}

Web表单

web表单是web应用程序的基本功能。

它是HTML页面中负责数据采集的部件。表单有三个部分组成:表单标签、表单域、表单按钮。表单允许用户输入数据,负责HTML页面数据采集,通过表单将用户输入的数据提交给服务器。

在Flask中,为了处理web表单,我们一般使用Flask-WTF扩展,它封装了WTForms,并且它有验证表单数据的功能

WTForms支持的HTML标准字段

字段对象

说明

StringField

文本字段

TextAreaField

多行文本字段

PasswordField

密码文本字段

DateField

文本字段,值为 datetime.date 文本格式

DateTimeField

文本字段,值为 datetime.datetime 文本格式

IntegerField

文本字段,值为整数

DecimalField

文本字段,值为decimal.Decimal

FloatField

文本字段,值为浮点数

BooleanField

复选框,值为True 和 False

RadioField

一组单选框

SelectField

下拉列表

SelectMutipleField

下拉列表,可选择多个值

FileField

文件上传字段

SubmitField

表单提交按钮

FormField

把表单作为字段嵌入另一个表单

FieldList

一组指定类型的字段

WTForms常用验证函数

验证函数

说明

DataRequired

确保字段中有数据

EqualTo

比较两个字段的值,常用于比较两次密码输入

Length

验证输入的字符串长度

NumberRange

验证输入的值在数字范围内

URL

验证URL

AnyOf

验证输入值在可选列表中

NoneOf

验证输入值不在可选列表中

使用Flask-WTF需要配置参数SECRET_KEY。 CSRF_ENABLED是为了CSRF(跨站请求伪造)保护。 SECRET_KEY用来生成加密令牌,当CSRF激活的时候,该设置会根据设置的密匙生成加密令牌。在HTML页面中直接写form表单:

示例

使用普通方式实现表单

在HTML页面中直接写form表单:
代码语言:javascript复制
<form method="post">
    <label>用户名:</label><input type="text" name="username"><br>
    <label>密码:</label><input type="password" name="password"><br>
    <label>确认密码:</label><input type="password" name="password2"><br>
    <input type="submit" value="提交"><br>
    {% for message in get_flashed_messages() %}
        {{ message }}
    {% endfor %}
</form>
视图函数中获取表单数据:
代码语言:javascript复制
from flask import Flask,render_template,request

app.secret_key = 'heima'

@app.route('/', methods=['GET', 'POST'])
def hello_world():

    # 1. 判断请求方式是post
    if request.method == 'POST':

        # 2. 获取参数, 并效验参数完整性, 如果有问题就进行flash
        username = request.form.get('username')
        password = request.form.get('password')
        password2 = request.form.get('password2')
        if not all([username, password, password2]):
            flash('params error')

        # 3. 效验密码
        elif password != password2:
            flash('password error')

        # 4. 没有问题就返回'success'
        else:
            print username
            return 'success'

    return render_template('wtf.html')

使用Flask-WTF实现表单

模板页面:
代码语言:javascript复制
<form method="post">
    {#设置csrf_token#}
    {{ form.csrf_token() }}
    {{ form.username.label }}{{ form.username }}<br>
    {{ form.password.label }}{{ form.password }}<br>
    {{ form.password2.label }}{{ form.password2 }}<br>
    {{ form.input }}<br>
</form>
视图函数:
代码语言:javascript复制
#coding=utf-8
from flask import Flask, render_template, request, flash
#导入wtf扩展的表单类
from flask_wtf import FlaskForm
#导入自定义表单需要的字段
from wtforms import SubmitField,StringField,PasswordField
#导入wtf扩展提供的表单验证器
from wtforms.validators import DataRequired,EqualTo
# 解决编码问题
import sys
reload(sys)
sys.setdefaultencoding("utf-8")

app = Flask(__name__)
app.config['SECRET_KEY']='heima'
#自定义表单类,文本字段、密码字段、提交按钮
# 需要自定义一个表单类

class RegisterForm(FlaskForm):
    username = StringField('用户名:', validators=[DataRequired()]})
    password = PasswordField('密码:', validators=[DataRequired()])
    password2 = PasswordField('确认密码:', validators=[DataRequired(), EqualTo('password', '密码输入不一致')])
    input = SubmitField('提交')

#定义根路由视图函数,生成表单对象,获取表单数据,进行表单数据验证
@app.route('/form', methods=['GET', 'POST'])
def form():
    register_form = RegisterForm()

    if request.method == 'POST':
        # 调用validate_on_submit方法, 可以一次性执行完所有的验证函数的逻辑
        if register_form.validate_on_submit():
            # 进入这里就表示所有的逻辑都验证成功
            username = request.form.get('username')
            password = request.form.get('password')
            password2 = request.form.get('password2')
            print username
            return 'success'

        else:
            #message = register_form.errors.get('password2')[0]
            #flash(message)
            flash('参数有误')

    return render_template('wtf.html', form=register_form)

0 人点赞