Flask 框架——模板

本文详细介绍了 Flask 框架中使用的 Jinja2 模板,包括模板渲染、过滤器、控制语句、宏和 import 语句、include 和 set 语句以及模板继承。讲解了如何使用 render_template 渲染模板,Jinja2 的过滤器如 length、default、join 等,以及 if/for 语句。还探讨了宏的创建和导入,以及模板继承的概念,强调了静态文件的配置和 url_for 的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模板

1. 模板简介

模板

模板是一个 web 开发必备的模块。因为我们在渲染一个网页的时候,并不是只渲染一个纯文本字符串,而是需要使用模板了。在 Flask 中,配套的模板是 Jinja2, Jinja2 的作者也是 Flask 的作者。这个模板非常的强大,并且执行效率高。以下对 Jingja2 做一个简单介绍!

Flask 渲染 Jinja 模板

要渲染一个模板,通过 render_template 方法即可。

from flask import Flask,reder_template
app=Flask(__name__)

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

当访问/about/ 的时候,about() 函数会在当前目录下的 templates 文件夹下寻找 about.html 模块文件。如果想更改模板文件地址,应该在创建 app 的时候,给 Flask 传递一个关键字参数 template_folder,指定具体的路径。

from flask import Flask,render_template
app=Flask(__name__,template_folder=r'路径')

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

以上例子将会在 C盘的 templates 文件夹中寻找模板文件。还有最后一点是,如果模板文件中有参数需要传递,应该怎么传呢

from flask import Flask,render_template
app=Flask(__name__)

@app.route('/about/')
def about():
    # return reder_template('about.html',user='luoji')
    return render_template('about.html',**{'user':'zhiliao'})

以上例子介绍了两种传递参数的方式,因为 render_template 需要传递的是一个关键字参数,所以第一种是顺其自然的。但是当你的模板中要传递的参数过多的时候,把所有参数放在一个函数中显然不是一个好的选择,因此我们使用字典进行包装,并且加两个 * 号,来转换成关键字参数。

2-Jinja2 模板过滤器

Jinja2 模板过滤器

过滤器是通过管道符号(|)进行使用,例如:{{name|length}},将返回name 的长度。过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,在返回相应的值,之后在将结果渲染到页面中。Jinja2 中内置了许多过滤器,在这里可以所有的过滤器。

  • abs(value):返回一个数值的绝对值。
<p>{{name|abs}}</p>  
  • default(value,default_value,boolean=false):如果当前变量没有值,则会使用参数中的值来代替。name|default(‘yuan’)——如果 name 不存在,则会使用 yuan 来代替。boolean=Flase 默认是在只有这个变量为 undefined 的时候才会使用 defaault 中的值,如果想使用 python 的形式判断是否为 false,则可以传递 boolean=true 或 content|e。
  • first(value):返回一个序列的第一个元素。names|first。
  • format(value,*arags,**kwargs):格式化字符串。例如以下代码:
    {{ "%s" - "%s"|format('Hello?',"Foo!") }}将输出:Helloo? - Foo!
  • last (value):返回一个序列的第一个元素。示例:names|last
  • length(value):返回一个序列或者字典的长度。示例:names|length。
  • join(value,d=u’’):将一个序列用 d 这个参数的值拼接成字符串。
  • safe(value):如果开启了全局转义,那么 safe 过滤器将会变量关掉转义。
  • int(value):将值转换为 int 类型。
  • float(value):将值转换为 float类型。
  • lower(value):将字符串转换为小写。
  • upper(value):将字符串转换为小写。
  • replace(value,old,new):替换将 old 替换为 new 的字符串。
  • truncate(value,length=255,killwords=Flase) 截取 length 长度的字符串。
  • striptags(value):删除字符串中所有的 HTML 标签,如果出现多个空格,将替换成一个空格。
  • trim:截取字符串前面和后面的空白字符。
  • wordcount(s):计算一个长字符串中单词的个数。

3. 控制语句

所有的控制语句都是放在(%…%) 中,并且有一个语句(% endxxx %)来进行结束,Jinja 中常用的控制语句有 if /for … in …

if:if 语句和 python 中的类似,可以使用 >,<, <=, >=,==,!= 来进行判断,也可以通过 and,or,not,() 进行逻辑合并操作。

{% if kenny.sick %}
    Kenny is sick
{% elif kenny.dead %}
    You killed Kenny! You bastard !!!
{% else %}
    Kenny  locks okay --- so far
{% endif %}

for …in…:for 循环可以遍历任何一个序列包括列表、字典、元组。并且可以进行反向遍历。

  • 普通的遍历
<ul>
    {% for user in users %}
        <li>{{user}}</li>
    {% endfor %}
</ul>
  • 遍历字典
<dl>
     {%  for user in users %}
         <li>{{user}}</li>
     {% endfor %}
 </di>
  • 如果序列中没有值得时候,进入else
<ul>
    {% for user in users %}
        <li>{{user.username}}</li>
    {% else %}
        <li>{<em>no users found</em></li>
    {% endfor %}   
</ul>

在 Jinja 中的循环还包含以下变量,可以用来获取当前的遍历状态。

变量描述
loop.index当前迭代的索引(从1开始)
loop.index0当前迭代的索引(从0开始)
loop.first是否是第一次迭代,返回True 或False
loop.last是否是最后一次迭代,返回True 或False
loop.length序列的长度

另外,不可以使用 continue 和 break 表达式来控制循环的执行。

4.宏和 import 语句

模板中的宏跟python 中的函数类似,乐意传递参数,但是不能有返回值,可以将一些经常用到的代码片段放到宏中,然后把一些不固定的值抽取出来当成一个变量。

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

以上例子抽取出了一个input标签,指定了一些默认参数。那么我妈们以后创建 input 标签的时候,可以通过他快速的创建:

<p>{{input('username')}}</p>
<p>{{input('password',type='password')}}</p>
import 语句

在真实的开发中,会将一些常用的宏单独放在一个文件中,在需要使用的时候,再从这个文件中进行导入。import 语句的用法跟 python 中的 import 类似,可以直接 import 语句的用法跟 python 中的 import 类似,可以直接 import…as…,也可以 from…import 或者 from…import…as…,假设现在有一个文件,叫做 forms.html,里面有两个宏分别为 input 和 textarea。

forms.html:
{% macro input(name,value='',type='text') %}
    <input type='{{type}}' value='{{value}}' name='{{name}}'>
{% endmacro %}

{% macro textarea(name,value='',rows=10,cols=40) %}
    <textarea name='{{name}}' rows='{{rows}}' cols='{{cols}}'>{{value|e}}</textarea>
导入宏的例子

1.import…as…形式

{% import 'macro.html' as macro %}
<tr>
    <td>用户名:</td>
    <td>{{macro.input('username')}}</td>
</tr>

2.from…import…as…/from…import…形式

{% from "macro.html" import input %}
<tr>
    <td>密码:</td>
    <td>{{ input('password',type='password') }}</td>
</tr>

另外需要注意的是,导入模板并不会把当前上下文中的变量添加到被导入的模板中,如果你想要导入一个需要访问当前上下文变量的宏,有两种可能的方法。

  • 显示地传入请求或请求对象的属性作为宏的参数。
  • 与上下文一起(with context)导入宏。

与上下文中一起(with context)导入的方式。

{% import ’macro.html‘ as macro with context %}

5-include 和 set 语句

include 语句

include 语句可以把一个模板引入到另一个模板中,类似于把一个模板的代码 copy 到另一个模板的指定位置。

{% include 'header.html' %}
    主体内容
{% include 'footer.html' %}
赋值(set)语句

有时候我们在再模板中添加变量,这时候赋值语句(set)就派上用场了。

{% set name='juran' %}

那么以后就可以使用 name 来代替 juran 这个值了,同时,也可以给他赋值为列表和元组:

{% set navigation=[('index.html','Index'),('about.html','About')] %}

赋值语句创建的变量在其之后都是有效的,如果不想让一个变量污染全局环境,可以使用 with 语句来创建一个内部的作用域,将 set 语句放在其中,这样创建的变量只在 with 代码块中才有效。

{% with %}
    {% set foo=42 %}
    {{foo}}    foo is 42 here
{% endwith %}

也可以在 with 的后面直接添加变量,比如以上的写法可以成这样:

{% with  foo=42 %}
     {{ foo }}
{% endwith %}

这两种方式都是等价的,一旦超出 with 代码块,就不能在使用 foo 这个变量了。

6-模板继承

Flask 中的模板可以继承,通过继承可以把模板中许多出现的元素抽取出来,放在父模板中,并且父模板通过定义 block 给子模板开一个口,子模板根据需要,再实现这个 block,假设现在有一个 base.html 这个父模板

<! DOCTYPE html>
<html lang='en'>
<head>
    <link rel='stylesheet' href='base.css'/>
    <title>{% block title %}{% endblock %}</title>
    {% block head %}{% endblock %}
<./head>
<body>
    <div id='body'>{% block body %}{% endblock %}</div>
    <div id='footer'>
        {% block fpoter %}
        &copy;Copyright 2008 by <a href='http://domain.invalid/'>you</a>
        {% endlock %}
    </div>
</body>
</html>

以上父模板中,抽取了所有模板都需要用到的元素 html、body 等,并且对于一些所有模板都要用到的样式文件 style.css 也进行了抽取,同时对于一些子模板需要重写的地方,比如 title、head、body 都定义成了 block,然后子模板可以根据自己的需要,再具体的实现。

{% extends 'base.html' %}
{% block title %}首页{% endblock %}
{% block head %}
    {{super()}}
    <style type='text/css'>
        .detail{
        color:red;
        }
    </style>
{% endblock %}
{%  block content %}
    <h1>这里是首页</h1>
    <p class= 'detail'>
        首页的内容
    </p>
{% endblock %}

首先第一行就定义了字模板继承的父模板,并且可以看到字模板实现了 title 这个 block,并填充了自己的内容,再看 head 这个 block ,里面调用了 super() 这个·函数,这个函数的目的是执行父模板中的代码,把父模板中的内容添加到字模板中,如果没有这一句,则父模板中处在 head 这个 block 中的代码将会被字模板中的代给覆盖掉。
另外,模板中不能出现重名的 block ,如果一个地方需要用到另外一个 block 中的内容,可以使用 self.blockname 的方式进行引用。

<title>
    {% block title %}
        这是标题
    {% endblock %}
</titl>
<h1>{{self.title() }}</h1>

以上示例中 h1 标签重用了 title 这个 block 中的内容,字模板实现 title 这个 block ,h1 标签也能拥有这个值。

另外,在字模板中,所有的文本标签和代码都要添加到从父模板中继承的 block 中。否则,这些文本和标签将不会被渲染。

静态文件的配置

Web 应用中出现大量的静态文件来使得网页更加生动美观。类似于CSS 样式文件、JavaScript 脚本文件、图片文件、字体文件等静态资源。在 Jinja 中加载静态文件非常简单,只需要通过 url_for 全局函数就可以实现。

<link href='{{url_for('static',filename='about.css')}}'>

url_for 函数默认会在项目跟目录下的 static 文件中寻找about.css 文件,如果找到了,会生成一个相对于项目跟目录下的 /static/about.css 路径。当然我们也可以把文件不放在 static 文件中,此时就需要具体指定了。

app=Flask(__name__,static_folder='C:\static')

那么访问静态文件的时候,将会到 /static 这个文件夹下寻找。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值