Flask(2)

模板 - Templates

一、什么是模板

   1、模板:模板是一个包含响应文本的文件(通常是html文件),在Flask 中就是允许响应给用户看的网页。
   2、该文件中允许包含"占位变量"来表示动态的内容,其具体值在请求中才能知道。"占位变量"最终会被真实的值所替换。
   3、模板最终也会被解析成字符串再响应给客户端,这一过程通常称为"渲染"。

   Flask中的模板是依赖于 Jinja2 的模板系统

二、模板的设置

     默认情况下,Flask会在程序文件夹中的 templates 的子文件夹中搜索模板。
     默认情况下,需要手动创建 templates 文件夹。    

三、模板的渲染

1、作用:

   在视图函数中,通过 return render_template()将模板文件(xx.html)渲染成字符串之后,再响应给客户端浏览器

2、函数:

 render_template('xxx.html',arg1=value1,arg2=value2)
        ex:return render_template('xxx.html')
        1、参数1 : xxx.html ,要渲染给客户端的html模板文件
        2、参数2 ~ n :要传递给模板动态显示的变量占位符,如果没有动态的变量占位符,则可以省略
        3、返回值:字符串

 1 from flask import Flask, render_template
 2 
 3 app = Flask(__name__)
 4 
 5 # 将 01-template.html 模板文件渲染成字符串再响应给客户端
 6 @app.route('/01-template')
 7 def template():
 8     # 将01-template.html渲染成字符串
 9    # return render_template('01-template.html')
10    # 渲染01-template.html ,并传递变量
11 
12     dic = {
13         'music':'绿光',
14         'author':'小强',
15         'qu':'小亮',
16         'singer':'小凡',
17     }
18     return render_template('01-template.html',params=dic)
19 
20 
21 if __name__ == "__main__":
22     app.run(debug=True)
01-template.py
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <style>
 7         h1{
 8             color:red;
 9         }
10     </style>
11 </head>
12 <body>
13     <h1>歌名:《{{params.music}}》</h1>
14     <h1>作词: {{params.author}}</h1>
15     <h1>作曲: {{params.qu}}</h1>
16     <h1>演唱: {{params.singer}}</h1>
17 </body>
18 </html>
01-template.html

四、模板中的语法(重难点)

1、变量

      变量是一种特殊的占位符,告诉模板引擎该位置的值是从渲染模板时的数据中获取出来的。
      1、在视图中 :
             @app.route('/')
             def index():
                 return render_template('xxx.html',变量1=值1,变量2=值2,..)
                     ex:return render_template('xxx.html',name='laowang',age=35)
                 注意:name 和 age  就是要传递到 xxx.html 中的变量
      2、在模板中:
             {{变量名}}
             <h1>{{name}}</h1>
    练习:
         在 01-template.html基础上,完成下列效果显示:
         歌名 :《绿光》
         作词 : 小强
         作曲 : 小亮
         演唱 : 小凡

 1 from flask import Flask, render_template
 2 
 3 app = Flask(__name__)
 4 
 5 # 将 01-template.html 模板文件渲染成字符串再响应给客户端
 6 @app.route('/01-template')
 7 def template():
 8     music = '绿光'
 9     author = '小强'
10     qu = '小亮'
11     singer = '小凡'
12 
13     #locals() : 将当前函数内所有的局部变量封装成一个字典
14     print(locals())
15     return render_template('01-template.html',params=locals())
16 
17 
18 if __name__ == "__main__":
19     app.run(debug=True)
01-template.py
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <style>
 7         h1{
 8             color:red;
 9         }
10     </style>
11 </head>
12 <body>
13     <h1>歌名:《{{params.music}}》</h1>
14     <h1>作词: {{params.author}}</h1>
15     <h1>作曲: {{params.qu}}</h1>
16     <h1>演唱: {{params.singer}}</h1>
17 </body>
18 </html>
01-template.html

     ----能够传递到模板中作为变量的数据类型都有:----

 1 from flask import Flask, render_template
 2 
 3 app = Flask(__name__)
 4 
 5 class Person(object):
 6     name = None
 7 
 8     def say(self):
 9         return "hello im a person"
10         
11 #目的:能够传递到模板中作为变量的数据类型都有
12 @app.route('/02-var')
13 def var():
14     uname = "my name is gebilaowang"
15     bookName = '钢铁是怎样炼成的'
16     author = '奥斯特罗夫斯基'
17     price = 32.5
18     list = ['漩涡鸣人','卡卡西','自来也','佐助']
19     tup = ('水浒传','三国演义','红楼梦','西游记')
20     dic = {
21         'WMZ':'小魏',
22         'WWC':'隔壁老王',
23         'LZ':'小泽',
24         'MM':'小蒙',
25     }
26     person = Person()
27     person.name = "狮王.金毛"
28     print(locals())
29     return render_template('02-var.html',params = locals())
30 
31 
32 if __name__ == "__main__":
33     app.run(debug=True)
02-var.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <!-- 过滤器 -->
    <h1>capitalize:{{params.uname|capitalize}}</h1>
    <h1>upper:{{params.uname|upper}}</h1>
    <h1>title:{{params.uname|title}}</h1>
    <!--
        {{params.uname}} : 变量不存在,但不会报错
        {{params.uname.len}} :
            当变量不存在时还试图去找对应的属性的话,则报错
    -->
    <h1>用户名:{{params.uname}}</h1>
    <h1>bookName : {{params.bookName}} </h1>
    <h1>bookName : {{params['bookName']}}</h1>
    <h1>author:{{params.author}}</h1>
    <h1>price:{{params.price}}</h1>
    <!-- 获取列表中的第一个元素 -->
    <h1>list[0]:{{params.list[0]}}</h1>
    <h1>list.0:{{params.list.0}}</h1>
    <!-- 获取元组中的第二个元素 -->
    <h1>tup[1] : {{params.tup[1]}}</h1>
    <h1>tup.1 : {{params.tup.1}}</h1>
    <!-- 获取字典中键为LZ的值-->
    <h1>dic['LZ'] : {{params.dic['LZ']}}</h1>
    <h1>dic.LZ : {{params.dic.LZ}}</h1>
    <!-- 获取 person 对象的 name 属性值 -->
    <h1>person.name : {{params.person.name}}</h1>
    <!-- 获取 person 对象的 say()  -->
    <h1>person.say() : {{params.person.say()}}</h1>
</body>
</html>
02-var.html

2、过滤器

       1、什么是过滤器
             过滤器是允许在变量输出显示之前改变变量的值
       2、语法
             {{变量|过滤器}}
          Jinja2 模板中常见过滤器:
             过滤器名            说明
             capitalize          首字符变大写,其他字符变小写
             lower                把值转换成小写
             upper               把值转换成大写
             title                  把值中的每个单词的首字符变大写
             trim                 去掉值两边的空格

3、标签

   1、什么是标签
           每个标签表示的是不同的服务器端的功能
   2、常用标签:
       1、if标签
             1)基本if结构
                 {% if 条件 %}
                 {% endif %}

            2)if ... else ... 结构
                 {% if 条件 %}
                     满足条件时要运行的代码
                 {% else %}
                     不满足条件时要运行的代码
                 {% endif %}
             3)if ... elif ... elif ... else
                 {% if 条件1 %}
                     满足条件1,要运行的代码
                 {% elif 条件2 %}
                     满足条件2,要运行的代码
                 {% elif 条件3 %}
                     满足条件3,要运行的代码
                 {% else %}
                     以上条件都不满足的时候,要运行的代码
                 {% endif %}

 1 from flask import Flask, render_template
 2 
 3 app = Flask(__name__)
 4 
 5 #目的:练习变量和if标签
 6 @app.route('/03-if')
 7 def if_views():
 8     return render_template('03-if.html')
 9 
10 @app.route('/user/login')
11 def login():
12     return "模拟登录的地址... ..."
13 
14 
15 if __name__ == "__main__":
16     app.run(debug=True)
03-if.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {% if uname %}
        <h1>欢迎:{{uname}}</h1>
    {% else %}
        <h1>
            <a href="{{url_for('login')}}">登录</a>
        </h1>
    {% endif %}
</body>
</html>
03-if.html

       2、for 标签
                 {% for 变量 in 元组|列表|字典 %}
                 {% endfor %}
             在 Jinja2 模板的循环中,支持内部变量 - loop
             loop作用:记载当前循环中的一些相关信息
             loop 常用属性   
                 1)index
                     用法:loop.index
                     作用:记录当前循环的次数,从1开始记录
                 2)index0
                     用法:loop.index0
                     作用:同上,从0开始记录
                 3)first
                     用法:loop.first
                     作用:值为True,则表示当前循环是第一次循环
                 4)last
                     用法:loop.last
                     作用:值为True,则表示当前循环是最后一次循环

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/04-for')
def for_views():
    list = ['孙悟空','猪八戒','周瑜','鲁班七号','孙尚香','大乔','沈梦溪']
    dic = {
        'SWK':'孙悟空',
        'PJL':'潘金莲',
        'XMQ':'西门庆',
        'WDL':'武大郎',
        'WWC':'王干娘',
    }
    return render_template('04-for.html',params = locals())


if __name__ == "__main__":
    app.run(debug=True)
04-for.py
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <!-- 将05-head.html包含进当前的模板文件中 -->
 9     {% include '05-head.html' %}
10 
11     <!-- 引入macro.html 并使用声明好的 宏 -->
12     {% import 'macro.html' as macros %}
13     <ul>
14         {% for str in params.list %}
15             {{macros.show_li(str)}}
16         {% endfor %}
17     </ul>
18 
19 
20     <!-- 声明一个宏 : 接收一个字符串参数,将该参数放在<p>打印输出 -->
21     {% macro showP(str) %}
22         <p style="background:orange;">{{str}}</p>
23     {% endmacro %}
24     <!-- 调用宏,循环遍历params.list,将遍历出来的每个数据都放在showP()中运行 -->
25     <h1>使用宏显示数据</h1>
26     {% for name in params.list %}
27         {{showP(name)}}
28     {% endfor %}
29 
30 
31     <!-- 循环遍历 params.list -->
32     {% for name in params.list %}
33         <!--<h1>{{name}}</h1>-->
34         <!--
35             第一项:背景颜色设置为红色
36             最后一项:背景颜色设置为黄色
37             否则:背景颜色设置为 粉色
38          -->
39         <!--{% if loop.first %}-->
40             <!--<h1 style="background:red;">{{name}}</h1>-->
41         <!--{% elif loop.last %}-->
42             <!--<h1 style="background:yellow;">{{name}}</h1>-->
43         <!--{% else %}-->
44             <!--<h1 style="background:deeppink;">{{name}}</h1>-->
45         <!--{% endif %}-->
46 
47         <h1 style="background:
48             {% if loop.first %}
49                 red
50             {% elif loop.last %}
51                 yellow
52             {% else %}
53                 deeppink
54             {% endif %}
55         ;">{{name}}</h1>
56 
57     {% endfor %}
58     <!--
59         循环遍历 params.dic
60         输出所有的内容: KEY:VALUE
61      -->
62     <h1>遍历所有的key</h1>
63     {% for key in params.dic.keys() %}
64         <h2>{{key}}</h2>
65     {% endfor %}
66     <h1>遍历所有的value</h1>
67     {% for value in params.dic.values() %}
68         <h2>{{value}}</h2>
69     {% endfor %}
70     <h1>遍历所有的key和value</h1>
71     {% for key,value in params.dic.items() %}
72         <h2>{{key}}:{{value}}</h2>
73     {% endfor %}
74 </body>
75 </html>
04-for.html
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <div class="container">
 9         <div class="top">
10             网页头部内容(LOGO,分类,登录,注册)
11         </div>
12         <ul>
13             <li>导航1</li>
14             <li>导航2</li>
15             <li>导航3</li>
16         </ul>
17     </div>
18 </body>
19 </html>
05-head.html
{% macro show_p(str) %}
    <p style="background:#f60;">{{str}}</p>
{% endmacro %}

{% macro show_li(str) %}
    <li>
        <p style="font-size:20px;">内容:</p>
        <span style="color:orange;">{{str}}</span>
    </li>
{% endmacro%}
macro.html

       3、macro 标签 (宏)
           1、作用
                  相当于是在模板中声明函数
           2、语法
                 使用 {% macro %} 标签声明宏
                 <!-- 声明 -->
                 {% macro 名称(参数列表) %}
                     xxxx  xxxx
                 {% endmacro %}
                 <!-- 调用 -->
                 {{show(uname)}}
                 et:
                     <!-- 声明 -->
                     {% mscro show(str) %}
                         <h1>{{str}}</h1>
                     {% endmacro %}

                     <!-- 调用 -->
                     {{show(uname)}}
           3、在独立的文件中声明宏
                 为了方便重复使用,允许将宏放在单独的模板文件中声明定义
               1、创建 macro.html 模板文件
                     作用:定义项目中要用到的所有的宏
                     ex:{% mscro show(str) %}
                             <h1>{{str}}</h1>
                            {% endmacro %}
               2、在使用的网页中,导入 macro.html
                     {% import 'macro.html' as macros %}  

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/05-static')
def static_views():
    return render_template('05-static.html')

if __name__ == "__main__":
    app.run(debug=True)
05-static.py
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <img src="/static/images/wxy.jpeg">
 9     <img src="http://localhost:5000/static/images/wxy.jpeg" alt="">
10 </body>
11 </html>
05-static.html

       4、include 标签(模板的包含)
             作用:将其他的模板文件包含到当前的模板文件中。
                  在多处重复使用的模板代码可以放在单独的文件中,可以被其他的模板所包含(引用)
             语法:{% include 'xxx.html' %}

      示例:见04-forhtml

五、静态文件处理

1、什么是静态文件

         在Flask中不能与服务器动态交互的文件都是静态文件
         如:图片,css文件,js文件,音视频文件,...
             <img src="images/a.jpg">
             <link rel="" href="css/a.css">
             <script src="js/a.js"></script>
             <video src="mp4/a.mp4"></video>
             <audio src="music/a.mp3"></audio>

2、静态文件的处理

  1、所有的静态文件必须放在名为 static 的目录中。static目录要放在项目的根目录处。
             结构:
             FlaskDemo02
                 run01.py
                 templates
                     01-xxx.html
                     02-xxx.html
                 static
                     images
                         a.jpg
                         b.jpg
                     js
                         body.js
                         slider.js
                     css
  2、所有的静态文件必须通过 /static/ 路径访问
             /static/images/a.jpg
             /static 要到静态资源目录中继续搜索
             ex:<img src="/static/资源路径">

  3、静态文件地址的反向解析
     url_for('static',filename='<file_path>')
     ex:
         <img src="{{url_for('static',filename='images/b04.jpg')}}">
         结果:/static/images/b04.jpg

from flask import Flask, render_template, url_for, request

app = Flask(__name__)


# 访问路径 http://localhost:5000/01-static
@app.route('/01-static')
def static_views():
    url = url_for('static',filename='images/b05.jpg')
    print(url)
    return render_template('01-static.html')


if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0')
06-static.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <img width="300" src="{{ url_for('static',filename='images/b05.jpg') }}">
</body>
</html>
06-static.html

六、模板的继承

1、什么是模板的继承

         模板的继承类似于类的继承,如果在一个模板中出现的大量内容是另外一个模板的话,那么就可以使用继承的方式来简化开发

2、语法

    1、父模板
             需要定义出哪些内容在子模板中是可以被重写的
             {% block 块名 %}
                 父模板中正常显示的内容
             {% endblock %}
             block:
                 定义允许在子模板中被修改的内容
                 1、在父模板中是可以正常显示的,没有任何影响
                 2、在子模板中是可以被重写的

from flask import Flask, render_template, url_for, request

app = Flask(__name__)


# 访问路径 http://localhost:5000/02-parent
@app.route('/02-parent')
def parent_views():
    return render_template('02-parent.html')


if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0')
07-parent.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>
        <a href="/04-request">去往04-request</a>
    </h1>
    <h1>这是parent的头部</h1>
    {% block content %}
    <h1>这是parent的主体内容</h1>
    {% endblock %}
    <h1>这是parent的底部</h1>
</body>
</html>
07-parent.html

    2、子模板
           1、需要指定继承来自哪个父模板
                 使用 {% extends '父模板名称' %} 来完成继承
           2、重写父模板中对应内容
                 使用 {% block 块名 %} 来重写父模板中的同名内容
                 {% block 块名 %}
                     此处编写的内容会覆盖掉父模板中同名block的内容。
                     允许通过 {{super()}} 来调用父模板中的内容。
                 {% endblock %}
                 ex:
                     {% extends '02-parent.html' %}
                     {% block content %}
                         {{ super() }}
                         <h1 style="color: red;">这是child主体</h1>
                     {% endblock %}

from flask import Flask, render_template, url_for, request

app = Flask(__name__)


# 访问路径 http://localhost:5000/03-child
@app.route('/08-child')
def child_views():
    return render_template('08-child.html')


if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0')
08-child.py
{% extends '07-parent.html' %}

{% block content %}
    {{ super() }}
    <h1 style="color:red;">这是 07-child 中的内容</h1>
{% endblock %}
08-child.html

七、修改配置

1、构建Flask 应用允许的指定配置信息

     app = Flask(__name__,template_folder='muban',static_url_path='/s',static_folder='/sta')
         1.template_folder
             指定存放模板的文件夹名称(设置模板的保存路径)
         2.static_url_path
             访问静态资源的路径(设置静态文件的访问路径,即映射到WEB中的访问路径)
             http://localhost:5000/s/xxx  查找静态资源文件
         3.static_folder
             指定存放静态文件的目录名称(映射到项目中的目录名称)
             在项目的根目录中 ,有一个名为 sta 的目录用于存放静态文件。   

2、启动程序的运行配置

         app.run(debug = True,port = 5555,host = '0.0.0.0')
         host : 指定访问地址,0.0.0.0 表示局域网内的任何机器都可以访问网站
         查看ip:ifconfig

posted on 2018-11-07 21:18  破天荒的谎言、谈敷衍  阅读(273)  评论(0)    收藏  举报

导航