当前位置: 首页 > news >正文

flask模板

做为python web开发领域的一员,flask跟Django在很多地方用法以都是相似的,比如flask的模板

模板就是服务器端的页面,在模板中可以使用服务端的语法进行输出控制

1.模板的工作原理

在视图函数中,通过render_template方法返回一个页面,然后通过Jinja2语法来进行渲染

简单来说,就是把服务器端的html页面解释成用户看到的页面,而视图函数是通过上下文对象来进行变量的传递

在项目开发中,视图函数经常会把一些服务器处理完成的变量传递给前端页面进行渲染,

比如在下面的例子中,由render_template返回html页面时,携带一些变量数据给Jinja2语法进行渲染

from flask import Flask, render_template

app = Flask(__name__)
app.debug = True

@app.route('/')
def hello_world():
    return 'Hello World!'

@app.route('/detail')
def detail():
    message = {
        'name':'jack',
        'text':'杰克'
    }
    return render_template('detail.html',info=message)

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

前端页面detail.html内容为:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>{{ info.name }}详细信息</h1>
<div>
    我的名字叫:{{ info.text }}
</div>
</body>
</html>

启动项目,浏览器打开http://127.0.0.1:5000/detail页面,前端页面渲染后效果为:

img_bc2810cbedcbf89c781f052ebc3b1195.png

那么此时,如果后台返回给前端的变量为一段html代码,返回给前端经过Jinja2语法渲染后,效果会是怎么样的呢??

2.Jinja2语法安全机制

修改message变量,然后由render_template返回

@app.route('/detail')
def detail():
    message = {
        'name':'jack',
        'text':'<h2>杰克</h2>'
    }
    return render_template('detail.html',info=message)

前端页面不变,刷新浏览器,效果如下

img_a8fd45a297cabbe745dd8ec98826fa4a.png

可以看到,返回的变量中包含html代码,但是Jinja2语法并没有对这一小段代码进行渲染,而是直接显示了出来

实际上这是为了安全,因为如果后台返回的html代码中包含恶意的js代码,如果直接就渲染了,会造成站点被攻击。

那如果我就是想渲染后台返回给前端的HTML代码,那应该怎么办呢

在flask中,如果确认后台返回给前端进行渲染的变量中包含的HTML代码是安全的,则可以使用一些方法来对这段HTML代码也进行渲染

方法一:autoescape 关闭安全机制

这种方法与Django的模板语法相同

后台代码不变,修改前端detail.html代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{% autoescape false %}
<h1>{{ info.name }}详细信息</h1>
<div>
    我的名字叫:{{ info.text }}
</div>
{% endautoescape %}
</body>
</html>

此时,再次刷新页面,查看效果

img_ad84d3f9749c351ad08c5a661d47c186.png

方法二,调用Jinja2的safe过滤器

如果觉得第一种方法有点麻烦,可以使用第二种方法

后台代码不变,同样修改detail.html页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>{{ info.name }}详细信息</h1>
<div>
    我的名字叫:{{ info.text | safe }}
</div>
</body>
</html>

此时,再次刷新页面,效果跟第一种方法一样

在flask中,Jinja2语法提供了很多过滤器,可以在下面的地址进行查找

http://jinja.pocoo.org/docs/dev/templates/

3.自定义过滤器

在写文章或博客的时候,很多时候都会用到Markdown语法

在flask的Jinja2语法中,并没有标准的Markdown语法过滤器,此时可以使用扩展来自定义Markdown语法过滤器

修改flask项目文件

from flask import Flask, render_template

app = Flask(__name__)
app.debug = True

@app.route('/')
def hello_world():
    return 'Hello World!'

@app.route('/detail')
def detail():
    message = {
        'name':'jack',
        'text':'<h2>杰克</h2>'
    }
    return render_template('detail.html',info=message,markdown='## Markdown编辑器<br>`注释`')

@app.template_filter('md')
def markdown_html(txt):
    from markdown import markdown
    return markdown(txt)

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

修改detail.html前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>{{ info.name }}详细信息</h1>
<div>
    我的名字叫:{{ info.text | safe }}
    {{ markdown | md | safe }}
</div>
</body>
</html>

刷新浏览器,查看效果

img_f7c13e625848d1f56e0d1c4c713ba757.png

在实际开发中,后台向模板中传递的不只有变量和filter,还可能会向前端传递一个方法,此时可以使用flask的上下文来实现

修改flask项目文件

#-*- coding: utf-8 -*-

from flask import Flask, render_template

app = Flask(__name__)
app.debug = True

@app.route('/')
def hello_world():
    return 'Hello World!'

def read_md(filename):
    from functools import reduce
    with open(filename,encoding='utf-8') as md_file:
        content = reduce(lambda x,y:x + y, md_file.readlines())
    return content

@app.context_processor
def methods():
    return dict(read_md=read_md)

@app.route('/detail')
def detail():
    message = {
        'name':'jack',
        'text':'<h2>杰克</h2>'
    }
    return render_template('detail.html',info=message,markdown='## Markdown')

@app.template_filter('md')
def markdown_html(txt):
    from markdown import markdown
    return markdown(txt)

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

如果想在Jinja2语法中调用后台定义的某个函数时,比如在这个例子中,前端页面中调用后台定义的read_md方法来处理某个Markdown格式的文件时,可以使用context_processor上下文处理器

在项目中应用了context_processor时,flask会把context_processor装饰的方法注册到Jinja2模板语法中来,这样就可以在Jinja2语法中调用后台的方法了

用context_processor装饰的后台方法可以在前端所有的Jinja2语法中调用
修改前端页面

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>{{ info.name }}详细信息</h1>
<div>
    我的名字叫:{{ info.text | safe }}
    {{ markdown | md | safe }}
    {{ read_md('editor.md') |md| safe}}
</div>
</body>
</html>

刷新浏览器,查看效果

img_314bba5554a68422ba3c83eb9e47dffa.png

使用过滤器和context_processor配置一起使用时,可以很灵活的进行页面的渲染

相关文章:

  • request.getParameter() request.getAttribute()
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 大数据时代事业单位利用数据分析提高工作效率
  • 服务(service)使用指南
  • 循环数组赋值给对象并push到数组中
  • spring源码解析bean初始化与依赖注入四
  • linux根分区满了如何处理,查找大文件方法
  • 机器中的灵魂会是量子比特么?
  • Android lrucache 实现与使用(Android内存优化)
  • 趣谈网络协议:像小说一样的网络协议入门课
  • 5.16 Stacks and Queues
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • Java 架构师眼中的 HTTP 协议
  • Java多线程干货系列—(四)volatile关键字
  • first
  • __proto__ 和 prototype的关系
  • 2017 前端面试准备 - 收藏集 - 掘金
  • AngularJS指令开发(1)——参数详解
  • CentOS7 安装JDK
  • css系列之关于字体的事
  • go语言学习初探(一)
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • Linux Process Manage
  • MD5加密原理解析及OC版原理实现
  • mysql innodb 索引使用指南
  • React-redux的原理以及使用
  • Vue2 SSR 的优化之旅
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 基于Android乐音识别(2)
  • 计算机在识别图像时“看到”了什么?
  • 前端技术周刊 2018-12-10:前端自动化测试
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 入门级的git使用指北
  • 收藏好这篇,别再只说“数据劫持”了
  • 我的面试准备过程--容器(更新中)
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • ​VRRP 虚拟路由冗余协议(华为)
  • # 数论-逆元
  • # 透过事物看本质的能力怎么培养?
  • #Linux(make工具和makefile文件以及makefile语法)
  • (6)设计一个TimeMap
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (pojstep1.3.1)1017(构造法模拟)
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (二十一)devops持续集成开发——使用jenkins的Docker Pipeline插件完成docker项目的pipeline流水线发布
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (牛客腾讯思维编程题)编码编码分组打印下标题目分析
  • (一)80c52学习之旅-起始篇
  • (转)c++ std::pair 与 std::make
  • (转)Linux整合apache和tomcat构建Web服务器
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • .net core开源商城系统源码,支持可视化布局小程序
  • .net 按比例显示图片的缩略图