返回顶部
首页 > 资讯 > 后端开发 > Python >Flask入门很轻松(三)—— 模板
  • 281
分享到

Flask入门很轻松(三)—— 模板

入门模板轻松 2023-01-31 00:01:08 281人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

转载请在文章开头附上原文链接地址:https://www.cnblogs.com/Sunzz/p/10959471.html flask内置的模板语言,它的设计思想来源于 Django 的模板引擎,并扩展了其语法和一系列强大的功能。 渲

转载请在文章开头附上原文链接地址:https://www.cnblogs.com/Sunzz/p/10959471.html

flask内置的模板语言,它的设计思想来源于 Django 的模板引擎,并扩展了其语法和一系列强大的功能。

渲染模版函数

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

模板基本使用

  1. 在视图函数中设置渲染模板
from flask import Flask, render_template
@app.route('/')
def index():
    return render_template('index.html')
  1. 项目下创建 templates 文件夹,用于存放所有的模板文件,并在目录下创建一个模板html文件 index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
我的模板html内容
</body>
</html>

{{}} 来表示变量名,这种 {{}} 语法叫做变量代码块

视图代码:

@app.route("/")
def index():
    title = "网页标题"
    return render_template("index.html",title=title)

模板代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{title}}</title>
</head>
<body>
    <h1>{{title}}</h1>
</body>
</html>

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

{{your_dict['key']}}
{{your_list[0]}}

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

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

使用 {# #} 进行注释,注释的内容不会在html中被渲染出来

{# {{ name }} #}

模板中特有的变量和函数

你可以在自己的模板中访问一些 Flask 默认内置的函数和对象

config

你可以从模板中直接访问Flask当前的config对象:

{{config.sqlALCHEMY_DATABASE_URI}}
sqlite:///database.db

request

就是flask中代表当前请求的request对象:

{{request.url}}
Http://127.0.0.1

session

为Flask的session对象

{{session.new}}
True

g变量

在视图函数中设置g变量的 name 属性的值,然后在模板中直接可以取出

{{ g.name }}

url_for()

url_for会根据传入的路由器函数名,返回该路由对应的URL,在模板中始终使用url_for()就可以安全的修改路由绑定的URL,则不比担心模板中渲染出错的链接:

{{url_for('home')}}

如果我们定义的路由URL是带有参数的,则可以把它们作为关键字参数传入url_for(),Flask会把他们填充进最终生成的URL中:

{{ url_for('post', post_id=1)}}
/post/1

流程控制

主要包含两个:

- if/else if /else / endif
- for / endfor

if语句

Jinja2 语法中的if语句跟 Python 中的 if 语句相似,后面的布尔值或返回布尔值的表达式将决定代码中的哪个流程会被执行:

{%if user.is_logged_in() %}
    <a href='/loGout'>Logout</a>
{% else %}
    <a href='/login'>Login</a>
{% endif %}

过滤器可以被用在 if 语句中:

{% if comments | length > 0 %}
    There are {{ comments | length }} comments
{% else %}
    There are no comments
{% endif %}

循环语句

  • 我们可以在 Jinja2 中使用循环来迭代任何列表或者生成器函数
{% for post in posts %}
    <div>
        <h1>{{ post.title }}</h1>
        <p>{{ post.text | safe }}</p>
    </div>
{% endfor %}
  • 循环和if语句可以组合使用,以模拟 Python 循环中的 continue 功能,下面这个循环将只会渲染post.text不为None的那些post:
{% for post in posts if post.text %}
    <div>
        <h1>{{ post.title }}</h1>
        <p>{{ post.text | safe }}</p>
    </div>
{% endfor %}
  • 在一个 for 循环块中你可以访问这些特殊的变量:
变量 描述
loop.index 当前循环迭代的次数(从 1 开始)
loop.index0 当前循环迭代的次数(从 0 开始)
loop.revindex 到循环结束需要迭代的次数(从 1 开始)
loop.revindex0 到循环结束需要迭代的次数(从 0 开始)
loop.first 如果是第一次迭代,为 True 。
loop.last 如果是最后一次迭代,为 True 。
loop.length 序列中的项目数。
loop.cycle 在一串序列间期取值的辅助函数。见下面示例程序。
  • 在循环内部,你可以使用一个叫做loop的特殊变量来获得关于for循环的一些信息
    • 比如:要是我们想知道当前被迭代的元素序号,并模拟Python中的enumerate函数做的事情,则可以使用loop变量的index属性,例如:
{% for post in posts%}
{{loop.index}}, {{post.title}}
{% endfor %}
  • 会输出这样的结果
1, Post title
2, Second Post
  • cycle函数会在每次循环的时候,返回其参数中的下一个元素,可以拿上面的例子来说明:
{% for post in posts%}
{{loop.cycle('odd','even')}} {{post.title}}
{% endfor %}
  • 会输出这样的结果:
odd Post Title
even Second Post

过滤器

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

使用方式:

  • 过滤器的使用方式为:变量名 | 过滤器。
{{variable | filter_name(*args)}}
  • 如果没有任何参数传给过滤器,则可以把括号省略掉
{{variable | filter_name }}
  • 如:``,这个过滤器的作用:把变量variable 的值的首字母转换为大写,其他字母转换为小写

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

{{ "hello world" | reverse | upper }}

常见的内建过滤器

字符串操作

  • 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>
  • reverse:字符串反转
<p>{{ 'olleh' | reverse }}</p>
  • fORMat:格式化输出
<p>{{ '%s is %d' | format('name',17) }}</p>
  • striptags:渲染之前把值中所有的HTML标签都删掉
<p>{{ '<em>hello</em>' | striptags }}</p>
  • truncate: 字符串截断
<p>{{ 'hello every one' | truncate(9)}}</p>

列表操作

  • 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>
<p>{{ [6,2,3,1,5,4] | sort }}</p>

语句块过滤

{% filter upper %}
    #一大堆文字#
{% endfilter %}

自定义过滤器

过滤器的本质是函数。当模板内置的过滤器不能满足需求,可以自定义过滤器。自定义过滤器有两种实现方式:

  • 一种是通过Flask应用对象的 add_template_filter 方法
  • 通过装饰器来实现自定义过滤器

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

需求:添加列表反转的过滤器

方式一

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

def do_listreverse(li):
    # 通过原列表创建一个新列表
    temp_li = list(li)
    # 将新列表进行返转
    temp_li.reverse()
    return temp_li

app.add_template_filter(do_listreverse,'lireverse')

方式二

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

@app.template_filter('lireverse')
def do_listreverse(li):
    # 通过原列表创建一个新列表
    temp_li = list(li)
    # 将新列表进行返转
    temp_li.reverse()
    return temp_li
  • 在 html 中使用该自定义过滤器
<br/> my_array 原内容:{{ my_array }}
<br/> my_array 反转:{{ my_array | lireverse }}
  • 运行结果
my_array 原内容:[3, 4, 2, 1, 7, 9] 
my_array 反转:[9, 7, 1, 2, 4, 3]

模板继承

在模板中,可能会遇到以下情况:

  • 多个模板具有完全相同的顶部和底部内容
  • 多个模板中具有相同的模板代码内容,但是内容中部分值不一样
  • 多个模板中具有完全相同的 html 代码块内容

像遇到这种情况,可以使用 JinJa2 模板中的 继承 来进行实现

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

  • 标签定义的内容
{% block top %} {% endblock %}
  • 相当于在父模板中挖个坑,当子模板继承父模板时,可以进行填充。
  • 子模板使用 extends 指令声明这个模板继承自哪个模板
  • 父模板中定义的块在子模板中被重新定义,在子模板中调用父模板的内容可以使用super()

父模板代码:

base.html

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

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

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

子模板代码:

  • extends指令声明这个模板继承自哪
{% extends 'base.html' %}
{% block content %}
 需要填充的内容
{% endblock content %}

模板继承使用时注意点:

  1. 不支持多继承
  2. 为了便于阅读,在子模板中使用extends时,尽量写在模板的第一行。
  3. 不能在一个模板文件中定义多个相同名字的block标签。
  4. 当在页面中使用多个block标签时,建议给结束标签起个名字,当多个block嵌套时,阅读性更好。

代码

config.py

class Config(object):
    DEBUG = True
    SECRET_KEY = "abcccddgadsag"

main.py

from flask import Flask
from config import Config
from flask import render_template

app = Flask(__name__,template_folder='templates')
app.config.from_object(Config)

from flask import session
@app.route("/set_session")
def set_session():
    session["username"] = 'request数据'
    return "ok"



from flask import g
@app.route("/")
def index():
    title = "网页标题"
    dict1 = {"id":1,"username":"xiaoming","money":20.5}
    love  = ['睡觉','吹牛','敲代码']
    g.list1 = ['睡觉','吹牛','敲代码']
    g.book_list = [
        {"id":1,"name":"浪潮之巅","price":88.5},
        {"id":12,"name":"数学之美","price":68.5},
        {"id":12,"name":"数学之美","price":68.5},
        {"id":12,"name":"数学之美","price":68.5},
        {"id":13,"name":"硅谷之谜","price":108.533333},
        {"id":14,"name":"五年高考三年模拟","price":78.5},
    ]

    g.title2 = '<script>alert("大标题")</script>'
    g.question = '如果x=10,x<y,y>z,求z的取值范围?'

    return render_template("index.html",title=title,dict1=dict1,love=love)

"""自定义过滤器"""

def rev(data):
    data.reverse()
    return data

app.add_template_filter(rev,'myrev')

@app.route("/filter")
def myfilter():

    g.list1 = ['睡觉', '吹牛', '敲代码']

    return render_template("f.html")

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

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{{title}}</title>
</head>
<body>
    <h1>{{title}}</h1>
    <table border="1" width="400">
        <tr>
            <th>ID</th>
            <th>姓名</th>
            <th>存款</th>
        </tr>
        <tr>
            <td>{{ dict1["id"] }}</td>
            <td>{{ dict1["username"] }}</td>
            <td>{{ dict1["money"] }}</td>
        </tr>
        <tr>
            <td>{{ dict1.id }}</td>
            <td>{{ dict1.username }}</td>
            <td>{{ dict1.money }}</td>
        </tr>
    </table>
    <ul>
        <li>{{ love.0 }}</li>
        <li>{{ love.1 }}</li>
        <li>{{ love.2 }}</li>

        <li>{{ love[0] }}</li>
        <li>{{ love[1] }}</li>
        <li>{{ love[2] }}</li>

        {# for循环也支持多层的嵌套或者其他语句 #}
        {% for item in love %}
        <li>{{ item }}</li>
        {% endfor %}

    </ul>

    {# 这里是if判断,if还可以支持多个条件的判断 #}
    {% if dict1.money < 20 %}
        <p>存款太少了,需要充值</p>
    {% endif %}

    {# 特殊变量 #}
    {# 支持直接读取配置信息 #}
    <p>{{ config.SECRET_KEY }}</p>

    {# 支持获取请求信息 #}
    <p>{{ request.method }}</p>

    {# 支持获取session数据 #}
    <p>{{ session.username }}</p>

    {# 支持获取g变量 #}
    <p>{{ g.list1 }}</p>

    {# 支持使用url_for生成地址 #}
    <a href="{{ url_for("set_session") }}">跳转到sesion</a>

    {# for循环中还内置了循环对象loop,可以操作循环过程中的索引 #}
    <table border="1" width="600">
        <tr>
            <th>序号</th>
            <th>ID</th>
            <th>书名</th>
            <th>价格</th>
        </tr>
        {% for book in g.book_list %}
        {% if loop.first %}
        <tr style="background-color: orange;">
        {% elif loop.last %}
        <tr style="background-color: blue;color: #fff;">
        {% else %}
        <tr>
        {% endif %}
            <td>{{ loop.revindex }}</td>
            <td>{{ "%03D" % book.id  }}</td>
            <td>{{ book.name }}</td>
            <td>{{ book.price }}</td>
        </tr>
        {% endfor %}
    </table>

    {# 过滤器 #}
    {{ dict1.username | upper | reverse }}

    {#
       默认情况下, flask会自动针对html标签进行实体化转移,目的时为了防止xss攻击
       但是,我们后端也会有一些包含样式的内容要输出页面中,此时可以使用 safe 过滤器
     #}
    {{ g.title2 | safe }}

    {# 这个过滤器会直接删除html标签,也是为了防止xss攻击,但是这个过滤器慎用,在遇到数学公式的时候,会误伤. #}
    {{ g.title2 | striptags }}
    {{ g.question | striptags }}


    {# 字符长度截取 #}
    <p>{{ 'hello every one' | truncate(9)}}</p>

{% filter upper %}
dasdasd
dsa
das
ds
ad
<p>{{ 'hello every one' | truncate(9)}}</p>
asd
asdas
{% endfilter %}

{{ "hwello" }}

</body>
</html>

在 Flask 项目中解决 CSRF 攻击

在 Flask 中, Flask-wtf 扩展有一套完善的 csrf 防护体系,对于我们开发者来说,使用起来非常简单

1 设置应用程序的 secret_key,用于加密生成的 csrf_token 的值

# session加密的时候已经配置过了.如果没有在配置项中设置,则如下:
app.secret_key = "#此处可以写随机字符串#"

2 导入 flask_wtf.csrf 中的 CSRFProtect 类,进行初始化,并在初始化的时候关联 app

from flask.ext.wtf import CSRFProtect
CSRFProtect(app)

3 在表单中使用 CSRF 令牌:

<form method="post" action="/">
    <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</form>

--结束END--

本文标题: Flask入门很轻松(三)—— 模板

本文链接: https://lsjlt.com/news/182610.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Flask入门很轻松(三)—— 模板
    转载请在文章开头附上原文链接地址:https://www.cnblogs.com/Sunzz/p/10959471.html Flask内置的模板语言,它的设计思想来源于 Django 的模板引擎,并扩展了其语法和一系列强大的功能。 渲...
    99+
    2023-01-31
    入门 模板 轻松
  • Flask入门很轻松 (一)
    转载请在文章开头附上原文链接地址:https://www.cnblogs.com/Sunzz/p/10956837.html Flask诞生于2010年,是Armin ronacher(人名)用 Python 语言基于 Werkzeug ...
    99+
    2023-01-31
    入门 轻松 Flask
  • Flask入门很轻松 (二)
    转载请在文章开头附上原文链接地址:https://www.cnblogs.com/Sunzz/p/10959454.html 在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如: 在请求开始时,建立数据库连接; 在请求...
    99+
    2023-01-31
    入门 轻松 Flask
  • Python Flask入门之模板
    目录模板基本语法 编写主页模板 准备虚拟数据 渲染主页模板 总结在一般的 Web 程序里,访问一个地址通常会返回一个包含各类信息的 HTML 页面。因为我们的程序是动态的,页面中的某...
    99+
    2024-04-02
  • Flask入门第三天
      一、数据库操作   1,orm orm(object-Relation Mapping),对象-关系映射,主要实现模型对象到关系数据库数据的映射。 优点: - 只需要面向对象编程, 不需要面向数据库编写代码. - 对数据库的操作...
    99+
    2023-01-31
    门第 Flask
  • python中的flask框架Jinja 模板入门教程
    目录1、快速体验2、Flask 最小 DEMO3、模板继承4、Super Blocks5、Macros6、自定义过滤器7、结论Flask 和 Django 附带了强大的 Jinja ...
    99+
    2024-04-02
  • VUE 第三方登录:从零到一,让您轻松入门
    一、了解第三方登录的概念 第三方登录是指用户可以使用其在其他平台(如QQ、微信、微博等)的账号,直接登录当前网站。这种方式简化了注册和登录流程,提高了用户体验。 第三方登录通常使用OAuth2.0协议,OAuth2.0是一种开放授权协议...
    99+
    2024-02-23
    VUE 第三方登录 OAuth2.0 JWT Token OpenID Connect
  • Goweb入门Gopongo2模板引擎
    目录下载 pongo2 函数库从字符串中读取模板从文件中读取文本Go pongo2 迭代Go pongo2 过滤Go pongo2 条件总结Go pongo2 教程展示了如何使用 p...
    99+
    2024-04-02
  • Flask模板继承深入理解与应用
    目录什么叫模板继承呢模板页完整代码什么叫模板继承呢 在我的理解就是:在前端页面中肯定有很多页面中有很多相同的地方,比如页面顶部的导航栏,底部的页脚等部分,这时候如果每一个页面都重写一...
    99+
    2024-04-02
  • JSONP入门:轻松实现跨域请求
    什么是JSONP? JSONP(JSON with Padding)是一种跨域请求技术,利用<script>标签来动态加载外部脚本,并执行返回的JSON数据。它利用浏览器的同源策略例外,允许脚本跨域请求数据,而不受安全限制。...
    99+
    2024-02-28
    JSONP、跨域请求、同源策略
  • PHP入门指南:模板方法模式
    PHP是一种流行的Web开发语言,被广泛应用于构建动态网页和Web应用程序。PHP支持许多不同的编程模式,包括面向对象编程、函数式编程和设计模式。其中,模板方法模式是一种常见的设计模式,它可以帮助开发人员构建可维护、可扩展的代码。什么是模板...
    99+
    2023-05-22
    PHP 模板方法 入门
  • Java轻松入门了解File类的使用
    目录概述构造方法基本介绍代码示例常用方法获取文件和目录的基本信息判断功能创建和删除功能目录遍历功能概述 要学习Java中的File类,首先我们要知道,在Java的API中File类的...
    99+
    2024-04-02
  • 轻松入门Java Spring Boot Security:全面指南
    Java Spring Boot Security是一个强大的库,用于在Java Spring Boot应用程序中保护资源。它提供开箱即用的安全性功能,例如身份验证、授权和防伪造请求。在本文中,我们将逐步介绍如何使用Java Spring...
    99+
    2024-02-02
    Spring Boot, Spring Security, Java, Authentication, Authorization
  • Node.js 入门:使用 OAuth 轻松进行认证
    引言 在当今互联世界中,用户期望使用各种应用程序和服务,而无需一遍又一遍地创建和管理凭据。为了满足这一需求,OAuth 协议应运而生,它允许用户通过第三方授权提供商(例如 Google、Facebook 或 Twitter)安全地授权应用...
    99+
    2024-02-19
    Node.js OAuth Express Passport.js 认证
  • C++入门之模板基础讲解
    目录前言引入模板函数模板模板的匹配原则模板的显示调用类模板注意1注意2总结 前言 今天博主将要介绍的内容是–模板,他在C++中具有非常重要的位置.至于什么是模板呢?我们请看...
    99+
    2024-04-02
  • 13.django入门01(django入门初探视图,模板,路由)
    一、django的基本使用流程。pip install django #安装django创建一个project: django-admin startproject mysite---mysite...
    99+
    2024-04-02
  • 一篇文章带你入门java模板模式
    目录Java设计模式-模板模式什么是模板模式?总结:Java设计模式-模板模式 什么是模板模式? 模板模式,顾名思义,就是通过模板拓印的方式。 定义模板,就是定义框架、结构、原型。定...
    99+
    2024-04-02
  • PHP Laravel框架:初学者轻松入门指南
    1. 安装环境 在开始学习Laravel框架之前,您需要确保已安装好以下环境: PHP 7.3或更高版本 Composer MySQL或其他兼容的数据库 Web服务器(如Apache或Nginx) Laravel框架(通过Compos...
    99+
    2024-02-06
    PHP Laravel 框架 入门 教程 初学者
  • Node.js PM2 入门指南:轻松管理 Node.js 进程
    自动重新启动:当 Node.js 进程意外崩溃时,PM2 可以自动重启它。 负载均衡:PM2 可以将请求负载平均地分配到多个 Node.js 进程上。 日志管理:PM2 可以将 Node.js 进程的日志集中管理,便于查看和分析。 进程...
    99+
    2024-02-12
    1. 简介 PM2 是一款轻量级 开源且易于使用的进程管理器 它可以帮助您轻松管理 Node.js 进程 PM2 主要具备以下特点:
  • PyTorch入门指南:在PyCharm中轻松安装PyTorch
    PyTorch是当前深度学习领域中备受瞩目的框架之一,它的易用性和灵活性受到很多开发者的喜爱。对于很多新手来说,安装PyTorch可能是一个挑战,尤其是在选择合适的开发环境时。本文将介...
    99+
    2024-02-27
    pytorch pycharm 安装
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作