第三章 jinja2模板引擎

目录

第三章 jinja2模板引擎

3.1模板引擎概述及简单实用

3.2向模板中传递参数

3.3模板中控制语句之if语句

3.3模板中控制语句之for语句

3.5 Flask的过滤器

3.6宏的定义及使用

3.7 set和with语句的使用

3.8 静态文件加载(引用多种文件)

3.9模板的继承

3.10 练习


第三章 jinja2模板引擎

在Flask中常用jinja2模板引擎实现复杂的页面渲染,jinja2是灵活,快速和安全的模板引擎技术。

本章主要涉及的知识点有:

  • 如何使用Flask渲染模板;

  • 在模板中引用一个或多个参数

  • if语句在模板中的使用

  • for语句在模板中的使用

3.1模板引擎概述及简单实用

思考:随着不同终端的兴起,开发人员如何写一份功能代码在所有设备上都能使用

高度重视前后端的分离,后段负责业务逻辑/数据访问,前端负责展现/交互逻辑

from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def index():
    return render_template('index.html')
@app.route('/user/<username>')
def user(username):
    return render_template('user.html')
if __name__ == '__main__':
    app.run()

我的理解就是把网页(html文件)挂在了服务器上

Flask通过render_template()函数来实现模板的渲染,使用jinja2模板引擎,需要from flask import render_template命令导入render_template函数。在视图函数中使用return方法,render_template()函数的首个函数声明使用哪个模板文件。

3.2向模板中传递参数

  • 单个变量

在app.py文件上把username=name

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

在html文件中带入参数,用{{}}

    <h1>欢迎您:{{name}} </h1>
  • 多个变量

在app.py文件中

def index():
    title ='python的键值对'
    author = 'jack'
    return render_template('index.html',**locals())
    或return render_template('index.html',var1=title,var2=title2)
    

在在html文件中

</head>
<body>
传过来的标题:{{title}}  或传过来的标题:{{var1}}
<br>
传过来的作者:{{author}} 或传过来的作者:{{var2}}
</body>

总结:在render_template()函数中,如果给模板传递全部本地变量,可以使用**locals()方法,

此时,在模板中可以使用{{title}} 和 {{author}}来直接表述变量。

3.3模板中控制语句之if语句

在app.py文件中

import random#导入random模块
app = Flask(__name__)#Flask初始化
@app.route('/') #定义路由
def hello_world():#定义视图函数
       rand1=random.randint(0,1)# 产生0-1范围内的整型数
       return render_template('index.html',name=rand1)#渲染模板,并向模板传递值

在html文件中

   </head>
   <body>
   {% if name %}<!-- name值是否存在-->
      <h1>产生的随机数有效!             </h1><!-- name值存在,则输出产生的随机数有效!-->
   {% else %}<!-- name值不存在-->
      <h1>产生的随机数无效!             </h1><!-- name值不存在,则输出产生的随机数无效!-->
   {% endif %}<!-- 结束if-->
   </body>

在此例子中random随机函数0无效,1有效,所以刷新页面有不同的效果。

由此,可以制作一个抽奖的随机系统(html文件)

建议:多使用if——elif——elif——else——endif 结构

   </head>
   <body>
   {% if name==0 %}
       <h1>重在参与</h1>
   {% elif name==1 %}
       <h1>恭喜,您抽得了一等奖</h1>
   {% elif name==2 %}
       <h1>恭喜,抽得了二等奖!</h1>
   {% else %}
       <h1>恭喜,抽得了三等奖!</h1>
   {% endif %}
   {{ name }}               <!--显示随机数-->
   </body>

总结:模板表达式都是在分隔符 {{}} 内的;

控制语句都是在 {% %} 内的;(注意紧密想连)

模板注释放在 {# #} 内。

3.3模板中控制语句之for语句

app.py文件

def hello_world():#定义视图函数
       goods = [{'name': '怪味少女开衫外套春秋韩版学生bf原宿宽松运动风2018新款秋装上衣',  'price': 138.00},
                {'name': 'A7seven 复古百搭牛仔外套女秋季2018新款宽松显瘦休闲夹克衫上衣',  'price': 100.00},
                {'name': '黑色时尚西装外套女春秋中长款2018新款韩版休闲薄款chic西服上衣', 'price': 100.00},
                {'name': 'HAVE RICE饭馆 颜值超耐打 复古牛仔外套女短款 2018春秋新款上衣', 'price': 129.00}
               ]#定义列表goods
       return render_template('shop.html', **locals())#渲染模板,并向模板传递参数

html文件(建表操作)

注意:正确写法{% for goods in goods %},不能{ %% },{和%必须紧密相连。

<table>
    <thead>
        <th>商品名称</th>
        <th>商品价格</th>
    </thead>
<tbody>
    <meta charset="UTF-8">
{% for goods in goods %}
<tr>
<td>{{goods.name}}
<td>{{goods.price}}
</tr>
{% endfor %}
</tbody>
</table>

在hello_world视图函数中定义一列表goods,期属性主要是name和price,用for语句将其遍历出来。 

总结:在模板中,使用if和for语句更好渲染模板,通过{%逻辑表达语句%}可以实现代码的嵌套,

与Python基本一致,但必须要在{%%}内部。

3.5 Flask的过滤器

过滤器本质就是一个转换函数,有时候我们不仅需要输出变量的值,还需要把某个变量的值修改在显现出来,

而在模板中不能直接调用Python中的某些方法,这莫就利用到了过滤器。

3.5.1常见过滤器(没运行出来)

列如:P42

app.py文件

#encoding:utf-8
from flask import Flask,render_template#导入Flask以及render_template模块
app = Flask(__name__)#Flask初始化
@app.route('/')#定义路由
def hello_world():#定义视图函数
     student={
         'name':'wangjie',
         'age':-18
     }
     return render_template('index.html',**student)#渲染模板,并向模板传递值
if __name__ == '__main__':
     app.run()

html文件

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8"><!--设置网页编码-->
    <title>过滤器</title><!--设置网页标题-->
 </head>
 <body>
 <p>{{ age|abs }}</p><!--对age进行绝对值运算-->
 <p>{{'hello'|capitalize}}</p><!--将字符串hello转化成Hello,实现首字母大些-->
 <p>{{'hello'|replace('h','x')}}</p><!--将hello中的字母h替换成x-->
 <p>{{[01,80,42,44,77]|first}}</p><!--取得列表中的首个元素-->
 <p>{{[01,80,42,44,77]|last}}</p><!--取得列表中的最后一个元素-->
 <p>{{[01,80,42,44,77]|count}}</p><!--取得列表中的元素中个数-->
 <p>{{[01,80,42,44,77]|sort}}</p><!--列表中的元素重新排序,默认按照升序进行排序  -->
 <p>{{[01,80,42,44,77]|join(',')}}</p><!--将列表中的元素合并为字符串    -->
 <p>{{18.8888|round(2,'floor')}}</p><!--保留小数点后2位,返回结果为18.88-->
 <p>{{18.8888|round}}</p><!--四舍五入取得整数 -->
 <p>{{-2|abs}}</p><!--进行绝对值运算 -->
 </body>
 </html>

3.5.2自定义过滤器(含不理解部分)

通过add_template_filter方法实现自定义过滤器,

第一个参数是函数名,第二个函数名自定义的过滤器名称。

app.py ——实现每三行输出一条分割线

#encoding:utf-8
import sys#导入sys模块
from flask import Flask,render_template#导入Flask和render_template模块
app = Flask(__name__)#Flask初始化
@app.route('/')#定义路由
 #视图函数
def hello_world():
     goods = [{'name': '怪味少女开衫外套春秋韩版学生bf原宿宽松运动风2018新款秋装上衣'},
              {'name': 'A7seven 复古百搭牛仔外套女秋季2018新款宽松显瘦休闲夹克衫上衣'},
              {'name': '黑色时尚西装外套女春秋中长款2018新款韩版休闲薄款chic西服上衣'},
              {'name': 'HAVE RICE饭馆 颜值超耐打 复古牛仔外套女短款 2018春秋新款上衣'},
              {'name': ' 颜值超耐打 复古牛仔外套女短款 2018春秋新款上衣'},
              {'name': 'HAVE RICE饭馆  复古牛仔外套女短款 2018春秋新款上衣'},
              {'name': 'HAVE RICE饭馆 颜值超耐打  2018春秋新款上衣'},
              {'name': 'HAVE RICE饭馆 颜值超耐打 复古牛仔外套女短款 '},
              {'name': 'HAVE RICE饭馆 颜值超耐打 复古牛仔外套女短款 2018春秋新款上衣end'},
              ]#定义列表goods
     return render_template('index.html',**locals())#渲染模板,并向模板传递值
def do_index_class(index):#定义函数
     if index % 3==0:#每间隔3行输出line
         return 'line'
     else:
         return ''
    
        <!--不李姐部分-->
app.add_template_filter(do_index_class,'index_class')#使用自定义过滤器添加css
​
if __name__ == '__main__':
    app.run()

html文件

 <!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8"><!--设定网页编码-->
     <title>Title</title><!--设定网页标题-->
     <style>
         .line{
             display: inline-block;
             height:1px;
             width:100%;
             background:#00CCFF;
             overflow:hidden;
            vertical-align: middle;
         }
     </style>
 </head>
 <body>
     <meta charset="UTF-8">
     {% for goods in goods %}<!--对列表进行遍历-->
     
     <!--不李姐部分-->
         <li style="list-style-type:none">{{ goods.name }}
             <span class="{{ loop.index | index_class }}">
         </span></li><!--每3条记录输出一条分割线-->
     
     
     {% endfor %}<!--for循环完毕-->
 </body>
 </html>

3.6宏的定义及使用

3.6.1宏的定义

jinja2中的宏功能有些类似于传统编程语言中的函数,它跟Python中函数类似,可以传递参数,

但不能有返回值,可以将一些经常用的代码放入宏中,然后把一些不固定的值取出来作为一个变量。

定义宏

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

定义宏要加macro,定义宏结束要加endmacro标志。宏的名称就是input,

他有三个参数,分别是name,type和value,后两个参数有默认值。

我们可以使用表达式来调用这个宏:

<!--调用宏-->
{{input('username')}}
{{input('password',type='password')}}

登录系统:html文件如下,app.py文件就是把html文件运用jinja模板render_template()

{#宏的定义 #}
{% macro input(name, type='text', value= '',size='40',placeholder="请在这里输入") -%}
    <input type="{{ type }}" name="{{ name }}" value="{{ value }}" size="{{ size }}" placeholder="placeholder">
{%- endmacro %}
{#宏的使用#}
<div style="color:red">
<p> 用户名 :{{ input('username')}}</p>
<p> 密  码 :{{ input('password',type='password')}}</p>
<p> 登  录 :{{ input('submit',type='submit',value='登录')}}</p>
</div>

3.6.2宏的导入

建立一个专门放宏的文件from.html

{% macro input(name, type='text', value= '' ,size=20, placeholder="请在这里输入用户名") -%}
    <input type="{{ type }}" name="{{ name }}" value="{{ value }}" size="{{ size }}",
           placeholder="{{ placeholder }}">
{%- endmacro %}

html文件,app.py文件不再赘述

{% from 'form.html' import input %}        <!--导入宏-->
 <div style="color:red">
  <p> 用户名 :{{ input('username')}}</p>
  <p> 密  码 :{{ input('password',type='password')}}</p>
   <p> 登  录 :{{ input('submit',type='submit',value='登录')}}</p>
  </div>

3.6.3 include的使用

宏文件中引用其他宏,可以使用include语句。include语句可以把一个模板引入到另一个模板中。

index.html-------主html文件

<style type="text/css">
        .header{
                width: 100%;
                height:40px;
                margin:20px 20px;
        }
        .footer{
               width: 100%;
                height: 40px;
                margin:20px 20px;
        }
        .content{
                width: 100%;
                height: 40px;
                margin:20px 20px;
        }
        </style>
</head>
<body>
{% include "header.html" %}
<div class="content">
这是网页内容
    </div>
{% include "footer.html" %}
    </body>

header.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<div class="header">
这是网页头部
</div>
</body>
</html>

3.7 set和with语句的使用

set与with语句都可以在jinja2中定义使用并赋予值。set定义的变量在整个模板范围内都有效。

with关键字在定义变量和与赋值同时,限制了with定义变量的作用范围。

  1. set用法

  • 给变量赋值

{% set telephone ='1388888888' %}
  • 给列表与数组赋值

 {% set nav = [('index.html', 'index'), ('product.html', 'product')] %}

在模板中使用{{telephone}}和{{nav}}来引用这些定义变量。

  1. with用法

   {% with pass = 60 %}
    {{ pass }}
    {% endwith %}

with定义变量的作用范围在{% with %}和{% endwith %}代码内,在模板的其他地方,引用此变量无效。

3.8 静态文件加载(引用多种文件)

静态文件的加载一般需要先新建文件夹static,在文件夹下在建立css、js和images文件夹,

在这里存放css、js、images,同时需要使用"url_for"函数

在template目录下新建一个名为index.html文件,在app.py的视图函数中使用

return render_template('index.html')方法来渲染模板。

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--加载js文件 两种方法-->
    
{#<script src="{{ url_for('static', filename='js/jquery-3.3.1/jquery-3.3.1.js') }}"></script>#}
<script type="text/javascript" src="static/js/jquery-3.3.1/jquery-3.3.1.js"></script>
    
    <!--加载外部css文件-->
<link rel="stylesheet" href="{{ url_for('static',filename='css/car.css') }}">
    
</head>
<body>
    
    <!--测试js文件是否加载成功-->
{#测试jquery是否加载#}
<script>
    if(jQuery) {
        alert('jQuery已加载!');
    }
    else {
        alert('jQuery未加载!');
    }
</script>
    
<div class="img">
    
    <!--加载外部图片文件-->
<img src="{{ url_for('static', filename='images/car.jpg') }}"></img>
​
    </div>
</body>

3.9模板的继承

在templates目录中创建index.html、base.html和product.html 3个静态文件。

base.html文件作为基类,index.html和product.html文件作为子类,子类去继承基类的基本内容。

base.html

<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %} -我的网站</title>
</head>
<body>
{% block body %}
    这是基类中的内容
{% endblock %}
</body>
</html>

index.html

{% extends "base.html" %}
{% block title %}网站首页{% endblock %}
{% block body %}
​
<!--子模板仍要保持父模板中的代码-->
    {{ super() }}
​
<h4>这是网站首页的内容!</h4>
{% endblock %}

product.html

{% extends "base.html" %}
{% block title %}产品列表页{% endblock %}
{% block body %}
<h4>这是产品列表页的内容!</h4>
​
<!--在一个block中调用其他block中的代码,用{{ self.其他block的名称() }}-->
<h4> 取得网页标题的内容:   {{ self.title() }}</h4>
​
{% endblock %}

3.10 练习

1.使用for语句,新建一个工程,打印出九九乘法表。

app.py

from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
    for i in range(1, 10):
        for j in range(1, i + 1):
            print(str(j) + str("*") + str(i) + "=" + str(i * j), end="\t")
        print()
    return 'Hello World!'
if __name__ == '__main__':
    app.run()

2.在视图函数中定义一个字典books,请在模板中遍历出字典的所有属性。

app.py

from flask import Flask,render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
    books = [
     {
     'name': '红楼梦',
     'author': '曹雪芹',
    'price': 200
    },
     {
      'name': '水浒传',
      'author': '施耐庵',
      'price': 100
    }
    ]
    return render_template('index.html',**locals())
​
​
if __name__ == '__main__':
    app.run()

index.html

   <!DOCTYPE html>
  <html lang="en">
   <head>
       <meta charset="UTF-8"><!-- 设定网页编码-->
       <title>Title</title><!-- 设定网页标题-->
   </head>
   <body>
   <table><!-- 定义表格-->
       <thead>
       <th>书名</th>
       <th>作者</th>
       <th>价格</th>
       </thead>
       <tbody>
       <meta charset="UTF-8">
       {% for books in books %}<!-- for循环开始-->
           <tr>
               <td>{{ books.name}}</td><!-- 显示商品名-->
               <td>{{ books.author}}</td><!-- 显示价格-->
               <td>{{ books.price}}</td><!-- 显示价格-->
           </tr>      {% endfor %}<!-- for循环结束-->
       </tbody>
   </table>
   </body>
   </html>
​

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

武师叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值