Flask模板

模板基本语法

{% if user %}
    {{ user }}
{% else %}
    hello!
<ul>
    {% for index in indexs %}
    <li> {{ index }} </li>
    {% endfor %}
</ul>

 

一 变量

在模板中{{ variable }}结构表示变量,是一种特殊的占位符,告诉模板引擎这个位置的值,从渲染模板时使用的数据中获取;Jinja2除了能识别基本类型的变量,还能识别{};

视图:

from flask import Flask, render_template

app = Flask(__name__)


@app.route("/index")
def index():
    data = {
        "name": "test",
        "size": 11,
        "adict": {"title": "index"},
        "alist": [1,2,3,4,5,6]
    }
    return render_template('index.html', **data)
    # return render_template("index.html", name="tile")


if __name__ == '__main__':
    app.run()
View Code

模板:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta http-equiv='Content-type' content='text/htm'>
</head>
<body>
<p>name---{{ name }}</p>
<p>size---{{ size }}</p>
<p>adict---title:{{ adict["title"] }}</p>
<p>adict---title:{{ adict.title }}</p>
<p>alist---{{ alist }}</p>
<p>alist---:alist[0]:{{ alist[0] }}</p>
<p>alist---:alist[2]:{{ alist.2 }}</p>
<p>alist---:alist[0]+alist[1]:{{ alist[0] + alist[1] }}</p>
<p>{{ "hello" + "flask" }}</p>
</body>
</html>
View Code

自定义错误页面:

@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404
View Code

 

二 过滤器

过滤器的本质就是函数。有时候我们不仅仅只是需要输出变量的值,我们还需要修改变量的显示,甚至格式化、运算等等,这就用到了过滤器。 过滤器的使用方式为:变量名 | 过滤器。 过滤器名写在变量名后面,中间用 | 分隔。如:{{variable | capitalize}},这个过滤器的作用:把变量variable的值的首字母转换为大写,其他字母转换为小写。 其他常用过滤器如下:

2.1 字符串过滤器:

safe:禁用转义;
  <p>{{ '<em>hello</em>' | safe }}</p>

capitalize:把变量值的首字母转成大写,其余字母转小写;
  <p>{{ 'hello' | capitalize }}</p>

lower:把值转成小写;
  <p>{{ 'HELLO' | lower }}</p>

upper:把值转成大写;
  <p>{{ 'hello' | upper }}</p>

title:把值中的每个单词的首字母都转成大写;
  <p>{{ 'hello' | title }}</p>

trim:把值的首尾空格去掉;
  <p>{{ ' hello world ' | trim }}</p>

reverse:字符串反转;
  <p>{{ 'olleh' | reverse }}</p>

format:格式化输出;
  <p>{{ '%s is %d' | format('name',17) }}</p>

striptags:渲染之前把值中所有的HTML标签都删掉;
  <p>{{ '<em>hello</em>' | striptags }}</p>

2.2 支持链式使用过滤器

<p>{{ “ hello world  “ | trim | upper }}</p>

2.3 列表过滤器

first:取第一个元素
  <p>{{ [1,2,3,4,5,6] | first }}</p>

last:取最后一个元素
  <p>{{ [1,2,3,4,5,6] | last }}</p>

length:获取列表长度
  <p>{{ [1,2,3,4,5,6] | length }}</p>

sum:列表求和
  <p>{{ [1,2,3,4,5,6] | sum }}</p>

sort:列表排序
  <p>{{ [6,2,3,1,5,4] | sort }}</p>

2.4 语句块过滤

{% filter upper %}
    this is a Flask Jinja2 introduction
  {% endfilter %}

2.5 自定义过滤器:

过滤器的本质是函数。当模板内置的过滤器不能满足需求,可以自定义过滤器。自定义过滤器有两种实现方式:一种是通过Flask应用对象的add_template_filter方法。还可以通过装饰器来实现自定义过滤器。

自定义的过滤器名称如果和内置的过滤器重名,会覆盖内置的过滤器。

实现方式一:通过调用应用程序实例的add_template_filter方法实现自定义过滤器。该方法第一个参数是函数名,第二个参数是自定义的过滤器名称。

def list_step_2(li):
    """自定义过滤器"""
    return li[::2]

# 注册过滤器
app.add_template_filter(list_step_2, "li2")
View Code

实现方式二:用装饰器来实现自定义过滤器。装饰器传入的参数是自定义的过滤器名称。

@app.template_filter("li3")
def list_step_3(li):
    """自定义过滤器"""
    return li[::3]
View Code

 

三 Web表单:

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

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

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

WTForms支持的HTML标准字段

 

字段对象说明
StringField文本字段
TextAreaField多行文本字段
PasswordField密码文本字段
HiddenField隐藏文本字段
DateField文本字段,值为datetime.date格式
DateTimeField文本字段,值为datetime.datetime格式
IntegerField文本字段,值为整数
DecimalField文本字段,值为decimal.Decimal
FloatField文本字段,值为浮点数
BooleanField复选框,值为True和False
RadioField一组单选框
SelectField下拉列表
SelectMultipleField下拉列表,可选择多个值
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表单:

#模板文件
<form method='post'>
    <input type="text" name="username" placeholder='Username'>
    <input type="password" name="password" placeholder='password'>
    <input type="submit">
</form>
View Code

视图函数中获取表单数据:

from flask import Flask,render_template,request

@app.route('/login',methods=['GET','POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        print username,password
    return render_template('login.html',method=request.method)
View Code

 

使用Flask-WTF实现表单。

pip install Flask-WTF

配置参数:

app.config['SECRET_KEY'] = '.........'

模板页面:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta http-equiv='Content-type' content='text/htm'>
</head>
<body>
<form method="post">
    {{ reg_form.csrf_token }}
{{ reg_form.username.label }}
<p>{{ reg_form.username }}</p>
{{ reg_form.username.errors.0 }}

{{ reg_form.password.label }}
<p>{{ reg_form.password }}</p>
{{ reg_form.password.errors.0 }}

{{ reg_form.repassword.label }}
<p>{{ reg_form.repassword }}</p>
{{ reg_form.repassword.errors.0 }}
<br>
{{ reg_form.submit }}
</form>

</body>
</html>
View Code

视图函数:

from flask import Flask, render_template, url_for, redirect, session
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, EqualTo
app = Flask(__name__)

app.config["SECRET_KEY"] = "ada898u2q11joloadad02"

class RegiterForm(FlaskForm):
    username = StringField(label="用户名", validators=[DataRequired("用户名不能为空")])
    password = PasswordField(label="密码", validators=[DataRequired("密码不能为空")])
    repassword = PasswordField(label="确认密码", validators=[DataRequired("确认密码不能为空"), EqualTo("password", "两次密码输入不一致")])
    submit = SubmitField(label="提交")


@app.route("/register", methods=['GET', "POST"])
def register():
    # 创建表单对象, 如果是post请求, 前端发送了数据,flask会把数据在构造form对象的数据,存在对象中
    reg_form = RegiterForm()

    # 判断form中的数据是否合法
    if reg_form.validate_on_submit():
        username = reg_form.username.data
        password = reg_form.password.data
        repassword = reg_form.repassword.data

        session["username"] = username

        print(username, password, repassword)
        return redirect(url_for("index"))
    return render_template('register.html', reg_form=reg_form)


@app.route("/index")
def index():
    username = session.get("username")
    return "hello %s " % username


if __name__ == '__main__':
    app.run()
View Code

 

四 控制语句

4.1 if控制语句

@app.route('/user')
def user():
    user = 'wusong'
    return render_template('user.html',user=user)
View Code
 <html>
 <head>
     {% if user %}
        <title> hello {{user}} </title>
    {% else %}
         <title> welcome to flask </title>        
    {% endif %}
 </head>
 <body>
     <h1>hello world</h1>
 </body>
 </html>
View Code

 

4.2 for循环语句

 @app.route('/loop')
 def loop():
    fruit = ['apple','orange','pear','grape']
    return render_template('loop.html',fruit=fruit)
View Code
<html>
 <head>
     {% if user %}
        <title> hello {{user}} </title>
    {% else %}
         <title> welcome to flask </title>        
    {% endif %}
 </head>
 <body>
     <h1>hello world</h1>
    <ul>
        {% for index in fruit %}
            <li>{{ index }}</li>
        {% endfor %}
    </ul>
 </body>
 </html>
View Code

 

五 宏、继承、包含

类似于python中的函数,宏的作用就是在模板中重复利用代码,避免代码冗余。

Jinja2支持宏,还可以导入宏,需要在多处重复使用的模板代码片段可以写入单独的文件,再包含在所有模板中,以避免重复。

5.1 宏

定义宏

{% macro input() %}
<input type="text" name="username" value="">
{% endmacro %}

调用宏

{{ input() }}

定义带参数的宏

{% macro input1(name, value="", type="text") %}
<input type="{{ type }}" name="{{ name }}" value="{{ value }}">
{% endmacro %}

调用宏,并传递参数

{{ input1(pwd, type="password") }}

把宏单独抽取出来,封装成html文件,其它模板中导入使用

文件名可以自定义macro_input.html

{% macro function() %}

    <input type="text" name="username" placeholde="Username">
    <input type="password" name="password" placeholde="Password">
    <input type="submit">
{% endmacro %}

在其它模板文件中先导入,再调用

{% import 'macro_input.html' as func %}
{{ func.function() }}

 

5.2模板继承

模板继承是为了重用模板中的公共内容。一般Web开发中,继承主要使用在网站的顶部菜单、底部。这些内容可以定义在父模板中,子模板直接继承,而不需要重复书写。

{% block top %}.......{% endblock %}标签定义的内容,相当于在父模板中挖个坑,当子模板继承父模板时,可以进行填充。

父模板:base.html

{% block top %}
    顶部菜单
  {% endblock top %}

  {% block content %}
  {% endblock content %}

  {% block bottom %}
    底部
  {% endblock bottom %}

子模板:

{% extends 'base.html' %}
  {% block content %}
   需要填充的内容
  {% endblock content %}

模板继承使用时注意点:

  • 不支持多继承。

  • 为了便于阅读,在子模板中使用extends时,尽量写在模板的第一行。

  • 不能在一个模板文件中定义多个相同名字的block标签。

  • 当在页面中使用多个block标签时,建议给结束标签起个名字,当多个block嵌套时,阅读性更好。

 

5.3包含(Include)

Jinja2模板中,除了宏和继承,还支持一种代码重用的功能,叫包含(Include)。它的功能是将另一个模板整个加载到当前模板中,并直接渲染。

示例:

include的使用

{% include 'hello.html' %}

包含在使用时,如果包含的模板文件不存在时,程序会抛出TemplateNotFound异常,可以加上ignore missing关键字。如果包含的模板文件不存在,会忽略这条include语句。

示例:

include的使用加上关键字ignore missing

{% include 'hello.html' ignore missing %}
  • 宏、继承、包含:
    • 宏(Macro)、继承(Block)、包含(include)均能实现代码的复用。

    • 继承(Block)的本质是代码替换,一般用来实现多个页面中重复不变的区域。

    • 宏(Macro)的功能类似函数,可以传入参数,需要定义、调用。

    • 包含(include)是直接将目标模板文件整个渲染出来。

 

六 Flask中的特殊变量和方法

在Flask中,有一些特殊的变量和方法是可以在模板文件中直接访问的。

config 对象:

config 对象就是Flask的config对象,也就是 app.config 对象。

{{ config.SQLALCHEMY_DATABASE_URI }}

request 对象:

就是 Flask 中表示当前请求的 request 对象,request对象中保存了一次HTTP请求的一切信息。

request常用的属性如下:

属性说明类型
data记录请求的数据,并转换为字符串*
form记录请求中的表单数据MultiDict
args记录请求中的查询参数MultiDict
cookies记录请求中的cookie信息Dict
headers记录请求中的报文头EnvironHeaders
method记录请求使用的HTTP方法GET/POST
url记录请求的URL地址string
files记录请求上传的文件*

 

{{ request.url }}

url_for 方法:

url_for() 会返回传入的路由函数对应的URL,所谓路由函数就是被 app.route() 路由装饰器装饰的函数。如果我们定义的路由函数是带有参数的,则可以将这些参数作为命名参数传入。

{{ url_for('index') }}

{{ url_for('post', post_id=1024) }}

get_flashed_messages方法:

返回之前在Flask中通过 flash() 传入的信息列表。把字符串对象表示的消息加入到一个消息队列中,然后通过调用 get_flashed_messages() 方法取出。

{% for message in get_flashed_messages() %}
    {{ message }}
{% endfor %}

示例:

from flask import Flask, render_template, flash

app = Flask(__name__)

app.config["SECRET_KEY"] = "diaj29u912kjwsle01sda"

flag = True

@app.route("/index")
def index():
    global flag
    if flag:
        flash("flash1")
        flash("flash2")
        flash("flash3")
        flag = False
    return render_template("index.html")


if __name__ == '__main__':
    app.run()
View Code
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta http-equiv='Content-type' content='text/htm'>
</head>
<body>
<h1>闪现</h1>
{% for msg in get_flashed_messages() %}
{{ msg }}
{% endfor %}

</body>
</html>
View Code

 

转载于:https://www.cnblogs.com/ForT/p/10789964.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值