2、Jinja2基础使用

2、Jinja2基础使用

首页模拟经营简单沙箱2更新时间:2024-04-16

jinja2

字符串传值

方式一

方式二

模版中使用url_for

过滤器

自定义过滤器

条件判断

for循环

方式一

方式二

宏的基本使用

导入宏

导入别的目录的宏

inclue

extends继承

set和with语句

加载静态文件

jinja2

在之前的章节中,视图函数只是直接返回文本,而在实际生产环境中其实很少这样用,因为实际的页面大多是带有样式和复杂逻辑的html代码,这可以让浏览器渲染出非常漂亮的页面。目前市面上有非常多的模板系统,其中最知名最好用的就是Jinja2,Jinja是日本寺庙的意思,并且寺庙的英文是temple和模板的英文template的发音类似。Jinja2是默认的仿Django模板的一个模板引擎,由Flask的作者开发。它速度快,被广泛使用,并且提供了可选的沙箱模板来保证执行环境的安全,让前端开发者和后端开发者工作分离。减少Flask项目代码的耦合性,页面逻辑放在模板中,业务逻辑放在视图函数中,将页面逻辑和业务逻辑解耦有利于代码的维护。提供了控制语句、继承等高级功能,减少开发的复杂度;

Flask渲染Jinja模板,通过render_template方法即可;

向模版传参有两种方式,第一种是用关键字参数的形式传递,第二种是直接传递一个字典;

字符串传值

从后端传递一个变量,并且在template中引用,然后在render的时候进行变量替换;

方式一

return render_template('home.html',username=username) # 等价于 return render_template('home.html', **data)

<p style="text-align: center;font-size: 20px;color: red">Hi,{{ username }}!</p>

方式二

传递字典,在模版中用对象的方式等三种取值方式;

data={

'username':'cce'

}

return render_template('home.html', data=data)

<p style="text-align: center;font-size: 20px;color: red">Hi,{{ data.username }} {{ data['username'] }} {{ data.get('username') }}!!</p>

模版中使用url_for

直接在模版中使用url_for,拿到登录的url;

@app.route('/')

def home():

data = {

'username': 'cce'

}

return render_template('home.html', data=data)

@app.route('/account/login')

def login():

return '登录成功'

<p>登录的URL为:{{ url_for('login',next='/') }}</p>

<a href="{{ url_for('login') }}">登录</a>

过滤器

过滤器是通过管道符(|)进行使用的,例如:{{ name|length }},将返回name的长度,过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能再返回对应的值,之后再将结果渲染到页面中;

abs(value):返回一个数值的绝对值。示例:-1|abs

default(value,default_value,boolean=false):如果当前变量没有值,则会使用参数中的值来代替。示例:name|default('xiaotuo')——如果name不存在,则会使用xiaotuo来替代。boolean=False默认是在只有这个变量为undefined的时候才会使用default中的值,如果想使用python的形式判断是否为false,则可以传递boolean=true。也可以使用or来替换。

escape(value)或e:转义字符,会将<、>等符号转义成HTML中的符号。示例:content|escape或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过滤器会将变量关掉转义。示例:content_html|safe。

int(value):将值转换为int类型。

float(value):将值转换为float类型。

lower(value):将字符串转换为小写。

upper(value):将字符串转换为小写。

replace(value,old,new): 替换将old替换为new的字符串。

truncate(value,length=255,killwords=False):截取length长度的字符串。

striptags(value):删除字符串中所有的HTML标签,如果出现多个空格,将替换成一个空格。

trim:截取字符串前面和后面的空白字符。

string(value):将变量转换成字符串。

wordcount(s):计算一个长字符串中单词的个数。

自定义过滤器

当jinja2内置的过滤不能够满足我们,那么我们就可以自定义过滤器了,示例如下;

# 将过滤器加入jinja2模版

@app.template_filter('length_3') # 指明过滤器的名字

# 定义过滤器

def length_3(value):

if len(value) < 3:

return value

return value[0:3]

<p>{{ '我只留三个字符' |length_3 }}</p>

条件判断

@app.route('/')

def home():

data = {

'name':'cce'

}

return render_template('home.html', **data)

<body>

{% if name == 'cce' %}

<p>cce</p>

{% elif name == 'cfj' %}

<p>cfj</p>

{% else %}

<p>None</p>

{% endif %}

</body>

for循环

loop.index:当前迭代的索引,从1开始;

loop.index0:当前迭代的索引,从0开始;

loop.first:是否是第一次迭代,Bool值;

loop.last:是否是最后一次迭代,Bool值;

loop.length:返回序列的长度;

方式一

@app.route('/')

def home():

data=['cce1','cce2','cce3']

return render_template('home.html', data=data)

<table border="1px" style="border-collapse:collapse;">

{% for datum in data %}

<tr>

<td>{{ datum }}</td>

<td>{{ loop.index }}</td>

<td>{{ loop.first }}</td>

<td>{{ loop.last }}</td>

<td>{{ loop.length }}</td>

<td>{{ loop.index0 }}</td>

</tr>

{% endfor %}

</table>

方式二

@app.route('/')

def home():

data = [

{'name':'cce','age':18},

{'name':'cfj','age':10},

]

return render_template('home.html', data=data)

<table border="1px" style="border-collapse:collapse;">

{% for data in data %}

<p>{{ data.get('name') }}</p>

<p>{{ data.get('age') }}</p>

{% endfor %}

</table>

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

宏的基本使用

<table border="1px" style="border-collapse:collapse;">

# 定义宏,可以设定默认值

{% macro macro_name(name,age,city='Wuhan') %}

<p>{{ name }}</p>

<p>{{ age }}</p>

<p>{{ city }}</p>

{% endmacro %}

# 调用宏

{{ macro_name('cce',18) }}

</table>

导入宏

在别的项目文件中导入宏,可以使用as来对宏的名字做别名,如果当前html和宏的文件不再同一个文件夹下面,那么可以使用../的方式导入;

// macros.html

{% macro macro_name(name,age,city='Wuhan') %}

<p>{{ name }}</p>

<p>{{ age }}</p>

<p>{{ city }}</p>

{% endmacro %}

{% from 'macros.html' import macro_name as macros %}

<!DOCTYPE html>

<html lang="en">

<head>

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

<meta charset="UTF-8">

<link rel="icon" href="http://jenkins.doorta.com/static/92c9360d/images/headshot.png">

<title>home</title>

</head>

<body>

<table border="1px" style="border-collapse:collapse;">

{{ macros('cce',18) }}

</table>

</body>

</html>

导入别的目录的宏

如果我们在宏中也想使用当前模版中的变量,那么我们可以使用with context将当前环境的所有变量全部传递给宏;

@app.route('/')

def home():

data = [

{'name':'cce','age':18},

{'name':'cfj','age':10},

]

return render_template('home.html', data=data)

// macros.html

{% macro macro_name(name,age,city='Wuhan') %}

<p>{{ name }}</p>

<p>{{ age }}</p>

<p>{{ city }}</p>

<p>{{ data }}</p>

{% endmacro %}

// index.html

{% import 'macros.html' as macros with context %} # 导入宏

<!DOCTYPE html>

<html lang="en">

<head>

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

<meta charset="UTF-8">

<link rel="icon" href="http://jenkins.doorta.com/static/92c9360d/images/headshot.png">

<title>home</title>

</head>

<body>

<table border="1px" style="border-collapse:collapse;">

{{ macros.macro_name('cce',18) }}

</table>

</body>

</html>

inclue

如果我们想要一个html文件里面所有代码重复利用,那么我们可以使用inclued来实现,注意inclued可以直接使用父模版文件的变量;

@app.route('/')

def home():

return render_template('home.html', name='cce') # 传递一个变量

// index.html

<!DOCTYPE html>

<html lang="en">

<head>

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

<meta charset="UTF-8">

<link rel="icon" href="http://jenkins.doorta.com/static/92c9360d/images/headshot.png">

<title>home</title>

</head>

<body>

{% include 'inclues.html' %}

</body>

</html>

// inclued.html

<p>这里的inclued,这里是变量{{ cce }}</p>

extends继承

模版继承可以把一些公用的代码单独抽取出来放到一个父模版中,以后子模版直接继承就可以使用,这样代码可以重复性使用,并且修改也比较方便,如果在block里面还是引用引用已经使用的blockk里面其他的block那么可以使用{{ self.block_name() }}来引用;

// base.html 父模版

<!DOCTYPE html>

<html lang="en">

<head>

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">

<meta charset="UTF-8">

<link rel="icon" href="http://jenkins.doorta.com/static/92c9360d/images/headshot.png">

{% block title %}

{% endblock %}

</head>

<body>

{% block body %}

{% endblock %}

</body>

</html>

// index.html 子模版

{% extends 'base.html' %} # 这一段的内容主要是将base.html里面文件全部导入进来,继承base.html,非block的内容

{% block title %} # 这段内容主要是对block里面的内容进行赋值

<title>cce</title>

{% endblock %}

{% block body %} # 这段内容主要是对block里面的内容进行赋值

{{ self.title() }} // 引用上面的block

<p>1</p>

{% endblock %}

set和with语句

set的主要作用和python的变量赋值相似,只要使用set设置了变量,那么在当前模版文件下,可以全局引用;

<body>

{% set username='cce' %}

<p>这里是set的值:{{ username }}</p>

</body>


with的主要作用和python的变量赋值相似,只要使用set设置了变量,那么在当前模版文件下,可以局部引用,局部就是在with代码块内部;

<body>

{% with username = 'cce' %}

{{ username }}

{% endwith %}

</body>

加载静态文件

默认是当前项目目录下面的static,如果有做修改可以在创建flask实例的时候指明,static_folder静态文件的路径,以当前项目为基准,static_url_path静态文件的访问路径;

app = Flask(__name__,static_folder='static',static_url_path='/static')

// 引用方式一

<link rel="stylesheet" href="/cce/cce.css">

// 引用方式二

<link rel="stylesheet" href="{{ url_for('static',filename="cce.css") }}">

查看全文
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved