Flask模板的介绍与使用

Flask模板的简单介绍

在Flask web程序中,通过业务逻辑函数得到的数据后,接下来需要根据这些数据生成HTTP响应(对于Web应用来说,HTTP响应是一个HTML文件)。在Flask Web开发中,一般是提供一个HTML模板文件,然后将数据传递到模板中,在渲染HTML模板文件后会得到最终的HTML响应文件。

使用Jinja2模板引擎

在Flask框架中,是使用Jinja2模板引擎对模板文件进行渲染,如果想要开发出一套易于维护的程序,那么就一定要将它的业务代码与逻辑代码分开。在Flask框架中,视图函数的作用是生成对访问请求的响应,一般来说,访问请求会改变程序的状态,而这种变化也会在视图函数中产生。在Flask程序中,业务逻辑部分也就是我们的后台,一般就是在python文件中编写,表现逻辑部分就会在HTML文件中编写,也就是模板文件。

在Flask程序中,模板文件是存储在templates文件夹中的,现在在templates文件夹中创建两个模板文件index.htmluser.html,它们的代码,如下所示:

index.html

<h1>Hello world</h1>

user.html

<h1>hello {{name}}</h1>

在默认的情况下,Flask在程序文件夹中,会自动寻找templates子文件夹中的模板文件。

接下来,新建一个moban.py文件,代码如下所示:

from flask import Flask, render_template


app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/user/<name>')
def user(name):
    return render_template('user.html', name=name)

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

在上述代码中使用Flask的内置函数render_template()引用Jinja2模板引擎。

render_template函数的用法:

(function) render_template: (template_name_or_list: str | List[str], **context: Any) -> str
Renders a template from the template folder with the given context.

:param template_name_or_list: the name of the template to be
                              rendered, or an iterable with template names the first one existing will be rendered
:param context: the variables that should be available in the
                context of the template.

第一个参数:表示本程序使用的模板文件名。

第二个参数:是一个“键-值”对,表示模板中变量对应的真实值。

Jinja2模板的基本元素

前面的Jinja2模板文件的index.html和user.html中,页面元素比较简单,在Jinja2模板文件中可以有更多的元素。

变量

在模板文件中user.html,“{{nme}}代码部分表示一个变量,功能是告诉模板引擎这个位置的信息是由业务逻辑进行处理。Jinja2非常强大,它除了可以识别普通变量之外,还可以识别其他类型的变量,例如列表、字典和对象等。

<p>字典中的值:{{mydict['key']}}</p>
<p>列表中的值:{{mydict[3]}}</p>
<p>列表中的值,具有可变索引:{{mydict[myintvar]}}</p>
<p>对象方法中的值:{{myjob.somemethod()}}</p>

过滤器

开发者如果想要修改变量的值,可以将过滤器添加到变量名的后面,在中间使用竖线进行隔离,例如,在模板文件中想要以首字母大写的形式显示变量name的值。

{{name | capitalize}}

Jinja2中常见的过滤器

(1)capitalize:把变量值的首字母转换成大写,将其他字母转换为小写。

(2)lower:把变量值全部转换为小写

(3)upper:把所有变量值转换为大写

(4)title:把变量中的所有单词的首字母都转换为大写

(5)trim:删除变量值中的首位空格

(6)stripags:在渲染前删除变量值中的所有HTML标签

下面代码将演示Flask Web中模板传递变量的方式。

untitled.py

from flask import Flask, render_template


class Myobj(object):
    def __init__(self, name) -> None:
        self.name = name
    
    def get_name(self):
        return self.name

app = Flask(__name__)


@app.route('/')
def index():
    mydict = {'key1': '123', 'key2': 'hello'}
    mylist = [123, 234, 456]
    myintvar = 0
    myobj = Myobj('Hyman')
    return render_template('index.html', mydict=mydict, mylist=mylist, myintvar=myintvar, myobj=myobj)


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

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p>一个来自字典的值:{{mydict['key']}}</p>
    <p>一个来自列表的值:{{mylist[3]}}</p>
    <p>一个来自具有变量索引的列表值{{mylist[myintvar]}}</p>
    <p>一个来自对象方法的值{{myobj.get_name()}}</p>
</body>
</html>

控制结构

Flask中的Jinja2模板提供了多种控制结构,通过这些控制结构可以改变模板的渲染过程。例如,下面展示的条件控制语句。

{ %if user %}
    你好{{user}},欢迎登录
{% else %}
    登录错误
{ %endif% }

接下来在下面掩饰for循环在模板中的使用。

<ul>
{% for user in users %}
    <li>用户列表:{{user}}</li>
{{% endfor %}}
</ul>

下面编写两个文件来实现控制结构与循环结构的使用。

app.py

from turtle import title
from flask import Flask, render_template


app = Flask(__name__)

@app.route('/')
def index():
    list1 = list(range(10))
    my_list = [
        {'id': 1, 'value': '我爱工作'},
        {'id': 2, 'value': '工作使人快乐'},
        {'id': 3, 'value': '沉迷工作无法自拔'},
        {'id': 4, 'value': '日渐消瘦'},
        {'id': 5, 'value': '以梦为马,不负韶华'},]
    
    return render_template('index.html', title='hello world',list2=list1,my_list=my_list)


def do_listreverse(aa):
    temp_li = list(aa)
    temp_li.reverse()
    return temp_li

app.add_template_filter(do_listreverse, 'listreverse')

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

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>{{title | listreverse | upper}}</h1>
    <br>
    <ul>
        {% for item in my_list %}
        <li>{{item.id}}----{{item.value}}</li>
        {% endfor %}
    </ul>

    <ul>
        {% for item in my_list %}
            {% if loop.index == 1 %}
                <li style="background-color: red;">{{loop.index}}----{{item.get('value')}}</li>
            {% elif loop.index == 2 %}
                <li style="background-color: gray;">{{loop.index}}----{{item.get('value')}}</li>
            {% elif loop.index == 3 %}
                <li style="background-color: blue;">{{loop.index}}----{{item.get('value')}}</li>
            {% else %}
                <li style="background-color: yellow;">{{loop.index}}----{{item.get('value')}}</li>
            {% endif %}
        {% endfor %}
    </ul>
</body>
</html>

静态文件

在flask web程序中也同样可以使用静态文件,假如你是使用Pycharm创建Flask项目,它会自动生成static文件夹,该文件夹就是用于存储静态文件,比如说图片、css文件和JavaScript文件等。

app.py

from flask import Flask, render_template


app = Flask(__name__)
@app.route('/')
def index():
    return render_template('index.html')


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

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript"
    src="{{url_for('static', filename='hello.js')}}"></script>
</head>
<body>
    <input type="button" onclick="sayhello()" value="点击我啊">
</body>
</html>

hello.js

function sayhello(){
    alert ("你好");
}

在上面的代码中,hello.js是保存在静态文件夹static中。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,980评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,422评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,130评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,553评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,408评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,326评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,720评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,373评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,678评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,722评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,486评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,335评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,738评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,283评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,692评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,893评论 2 335

推荐阅读更多精彩内容