• 03.flask模板


    配套视频教程

    本文B站配套视频教程

    模板概述

    一. 为什么要使用模板

    视图函数有两个作用, 一个是业务逻辑一个是表现逻辑, 举例说明:

    用户在网站注册了一个新账号, 用户在表单中输入电子邮件地址和密码, 点击提交按钮, 服务器接收到包含用户输入的请求, 然后Flask把请求分发到处理注册请求的视图函数。 这个视图函数需要访问数据库, 添加新用户(业务逻辑), 然后生成相应回送浏览器(表现逻辑)。

    两个完全独立的作用被混淆到一起会使代码难以理解和维护, 所以我们选择把表现逻辑(响应)迁移到模板当中去。

    模板是包含响应文本的文件,其中包含用占位变量表示的动态部分,其具体值只在请求的上下文中才能知道。使用真实值替换变量,再返回最终得到的响应字符串,这一过程称为渲染。为了渲染模板,Flask 使用一个名为 Jinja2 的强大模板引擎。

    二. 如何使用模板

    1. 如何渲染模板:
      • 模板放在templates文件夹下
      • flask中导入render_template函数。
      • 在视图函数中,使用render_template函数,渲染模板。注意:只需要填写模板的名字,不需要填写templates这个文件夹的路径。
    2. 模板传参:
      • 如果只有一个或者少量参数,直接在render_template函数中添加关键字参数就可以了。
      • 如果有多个参数的时候,那么可以先把所有的参数放在字典中,然后在render_template中,
        使用两个星号,把字典转换成关键参数传递进去,这样的代码更方便管理和使用。
    3. 在模板中,如果要使用一个变量,语法是:{{params}}
    4. 访问模型中的对象属性或者是字典,可以通过{{params.property}}的形式,或者是使用{{params['age']}}.

    示例代码

    template01 .py

    #encoding: utf-8
    from flask import Flask,render_template
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        # 类
        class Person(object):
            name = u'p17bdw'
            age = 18
    
        p = Person()
    
        context = {
            'username': u'c17bdw',
            'gender': u'男',
            'age': 17,
            'person': p,    # 声明
            'websites': {
                'baidu': 'www.baidu.com',
                'google': 'www.google.com'
            }
        }
        return render_template('anthoer/index.html',**context)
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    anthoer/index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        这是HTML文件中出现的文字
        <p>用户名:{{ username }}</p>
        <p>性别:{{ gender }}</p>
        <p>年龄:{{ age }}</p>
    
        <hr>
        <p>名字:{{ person['name'] }}</p>
        <p>年龄:{{ person.age }}</p>
    
        <hr>
        <p>百度:{{ websites['baidu'] }}</p>
        <p>谷歌:{{ websites['google'] }}</p>
    </body>
    </html>
    

    if判断

    1. 语法:
      {% if xxx %} {% else %} {% endif %}

    2. if的使用,可以和python中相差无几。

    示例代码

    if_statement .py

    # 输入 http://127.0.0.1:5000/1/ 为登录状态,否则为未登录状态。
    
    #encoding: utf-8
    
    from flask import Flask,render_template
    
    app = Flask(__name__)
    
    @app.route('/<is_login>/')
    def index(is_login):
        if is_login == '1':
            user = {
                'username': u'17bdw',
                'age':20
            }
            return render_template('index.html',user=user)
        else:
            return render_template('index.html')
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        {% if user and user.age > 18 %}
            <a href="#">{{ user.username }}</a>
            <a href="#">注销</a>
        {% else %}
            <a href="#">登录</a>
            <a href="#">注册</a>
        {% endif %}
    </body>
    </html>
    

    for循环遍历列表和字典

    1.  字典的遍历,语法和`python`一样,可以使用`items()`、`keys()`、`values()`、`iteritems()`、`iterkeys()`、`itervalues()`
        `{% for k,v in user.items() %} <p>{{ k }}:{{ v }}</p> {% endfor %}`
    2.  列表的遍历:语法和`python`一样。
        `{% for website in websites %} <p>{{ website }}</p> {% endfor %}`
    

    示例代码

    for_statement .py

    #encoding: utf-8
    
    from flask import Flask,render_template
    
    app = Flask(__name__)
    
    # for遍历字典
    
    @app.route('/')
    def index():
        books = [
            {
                'name': u'西游记',
                'author': u'吴承恩',
                'price': 109
            },
            {
                'name': u'红楼梦',
                'author': u'曹雪芹',
                'price': 200
            },
            {
                'name': u'三国演义',
                'author': u'罗贯中',
                'price': 120
            },
            {
                'name': u'水浒传',
                'author': u'施耐庵',
                'price': 130
            }
        ]
        return render_template('index.html',books=books)
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    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>
            {% for book in books %}
                <tr>
                    <td>{{ book.name }}</td>
                    <td>{{ book.author }}</td>
                    <td>{{ book.price }}</td>
                </tr>
            {% endfor %}
        </tbody>
    </table>
    
    </body>
    </html>
    

    过滤器

    1. 介绍和语法:

      • 介绍:过滤器可以处理变量,把原始的变量经过处理后再展示出来。作用的对象是变量。
      • 语法:
        {{ avatar|default('xxx') }}
    2. default过滤器:如果当前变量不存在,这时候可以指定默认值。

    3. length过滤器:求列表或者字符串或者字典或者元组的长度。

    4. 常用的过滤器:
      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
      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):计算一个长字符串中单词的个数。

    示例代码

    filter_demo .py

    #encoding: utf-8
    
    from flask import Flask,render_template
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        comments = [
            {
                'user': u'admin',
                'content': 'xxxx'
            },
            {
                'user': u'tesr',
                'content': 'xxxx'
            }
        ]
        return render_template('index.html',comments=comments)
    
    if __name__ == '__main__':
        app.run(debug=True)
    

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>过滤器</title>
    </head>
    <body>
    
    # 如果avatar这个变量不存在,就使用default过滤器提供的值
    
    <img src="{{ avatar|default('http://avatar.csdn.net/1/D/B/3_hmzkekek41.jpg') }}" alt="">
    
    <hr>
    
    # length 计算长度
    <p>评论数:({{ comments|length }})</p>
    <ul>
        {% for comment in comments %}
            <li>
                <a href="#">{{ comment.user }}</a>
                <p>{{ comment.content }}</p>
            </li>
        {% endfor %}
    
    </ul>
    </body>
    </html>
    

    继承和block

    1. 继承作用和语法:

      • 作用:可以把一些公共的代码放在父模板中,避免每个模板写同样的代码。
      • 语法:

      {% extends 'base.html' %}

    2. block实现:

      • 作用:可以让子模板实现一些自己的需求。父模板需要提前定义好。
      • 注意点:字模板中的代码,必须放在block块中。

    示例代码

    app.py

    #encoding: utf-8
    
    from flask import Flask,render_template
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        return render_template('index.html')
    
    @app.route('/login/')
    def login():
        return render_template('login.html')
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    

    index.html

    
    {% extends 'base.html' %}
    
    {% block head %}
        <style>
    
        </style>
        <link rel="stylesheet" href="">
        <script></script>
    {% endblock %}
    
    {% block title %}
        首页
    {% endblock %}
    
    {% block main %}
        <h1>这是首页</h1>
    {% endblock %}
    

    base.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}{% endblock %}</title>
            <style>
            .nav{
                background: #3a3a3a;
                height: 65px;
            }
            ul{
                overflow: hidden;
            }
            ul li{
                float: left;
                list-style: none;
                padding: 0 10px;
                line-height: 65px;
            }
            ul li a{
                color: #fff;
            }
        </style>
        {% block head %}{% endblock %}
    </head>
    <body>
    <div class="nav">
        <ul>
            <li><a href="/">首页</a></li>
            <li><a href="/login">发布问答</a></li>
        </ul>
    </div>
    {% block main %}{% endblock %}
    </body>
    </html>
    

    login.html

    {% extends 'base.html' %}
    
    {% block title %}
        登录
    {% endblock %}
    
    {% block main %}
        <h1>这是登录页面</h1>
    {% endblock %}
    

    使用Flask-Bootstrap集成Bootstrap

    Bootstrap 是 Twitter 开发的一个开源 Web 框架,它提供的用户界面组件可用于创建整洁且具有吸引力的网页,而且兼容所有现代的桌面和移动平台 Web 浏览器。

    要想在应用中集成 Bootstrap,最直接的方法是根据 Bootstrap 文档中的说明对 HTML 模板进行必要的改动。不过,这个任务使用 Flask 扩展处理要简单得多,而且相关的改动不会导致主逻辑凌乱不堪。

    我们要使用的扩展是 Flask-Bootstrap,它可以使用 pip 安装:

    (venv) $ pip install flask-bootstrap
    

    Flask 扩展在创建应用实例时初始化。

    初始化 Flask-Bootstrap。

    from flask_bootstrap import Bootstrap
    # ...
    bootstrap = Bootstrap(app)
    
    @app.route('/user/<name>')
    def user(name):
        return render_template('user.html', name=name)
    

    扩展通常从 flask_<name> 包中导入,其中 <name> 是扩展的名称。多数 Flask 扩展采用两种初始化方式中的一种。在示例中,初始化扩展的方式是把应用实例作为参数传给构造函数。

    初始化 Flask-Bootstrap 之后,就可以在应用中使用一个包含所有 Bootstrap 文件和一般结构的基模板。应用利用 Jinja2 的模板继承机制来扩展这个基模板。

    templates/user.html:使用 Flask-Bootstrap 的模板

    {% extends "bootstrap/base.html" %}
    
    {% block title %}Flasky{% endblock %}
    
    {% block navbar %}
    <div class="navbar navbar-inverse" role="navigation">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle"
                data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="/">Flasky</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a href="/">Home</a></li>
                </ul>
            </div>
        </div>
    </div>
    {% endblock %}
    
    {% block content %}
    <div class="container">
        <div class="page-header">
            <h1>Hello, {{ name }}!</h1>
        </div>
    </div>
    {% endblock %}
    
    

    Jinja2 中的 extends 指令从 Flask-Bootstrap 中导入 bootstrap/base.html,从而实现模板继承。Flask-Bootstrap 的基模板提供了一个网页骨架,引入了 Bootstrap 的所有 CSS 和 JavaScript 文件。

    上面这个 user.html 模板定义了 3 个区块,分别名为 titlenavbar 和 content。这些区块都是基模板提供的,可在衍生模板中重新定义。title 区块的作用很明显,其中的内容会出现在渲染后的 HTML 文档头部,放在 <title> 标签中。navbar 和 content 这两个区块分别表示页面中的导航栏和主体内容。

    在这个模板中,navbar 区块使用 Bootstrap 组件定义了一个简单的导航栏。content 区块中有个 <div> 容器,其中包含一个页头。之前版本中的欢迎消息,现在就放在这个页头里。改动之后的应用如图所示。

    url链接

    使用url_for(视图函数名称)可以反转成url。

    在模板中直接编写简单路由的 URL 链接不难,但对于包含可变部分的动态路由,在模板中构建正确的 URL 就很困难了。而且,直接编写 URL 会对代码中定义的路由产生不必要的依赖关系。如果重新定义路由,模板中的链接可能会失效。

    为了避免这些问题,Flask 提供了 url_for() 辅助函数,它使用应用的 URL 映射中保存的信息生成 URL。

    url_for() 函数最简单的用法是以视图函数名作为参数,返回对应的 URL。例如,在当前版本的 app.py 应用中调用 url_for('index') 得到的结果是 /,即应用的根 URL。调用 url_for('index', _external=True) 返回的则是绝对地址,在这个示例中是 http://localhost:5000/。

    使用 url_for() 生成动态 URL 时,将动态部分作为关键字参数传入。例如,url_for('user', name='john', _external=True) 的返回结果是 http://localhost:5000/user/john。

    传给 url_for() 的关键字参数不仅限于动态路由中的参数,非动态的参数也会添加到查询字符串中。例如,url_for('user', name='john', page=2, version=1) 的返回结果是 /user/ john?page=2&version=1。

    加载静态文件

    Web 应用不是仅由 Python 代码和模板组成。多数应用还会使用静态文件,例如模板中 HTML 代码引用的图像、JavaScript 源码文件和 CSS。

    在前一章中审查 app.py 应用的 URL 映射时,其中有一个 static 路由。这是 Flask 为了支持静态文件而自动添加的,这个特殊路由的 URL 是 /static/。例如,调用 url_for('static', filename='css/styles.css', _external=True) 得到的结果是 http://localhost:5000/static/css/styles.css。

    默认设置下,Flask 在应用根目录中名为 static 的子目录中寻找静态文件。如果需要,可在 static 文件夹中使用子文件夹存放文件。服务器收到映射到 static 路由上的 URL 后,生成的响应包含文件系统中对应文件里的内容。

    1. 语法:url_for('static',filename='路径')
    2. 可以加载css文件,可以加载js文件,还有image文件。

    第一个:加载css文件

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

    第二个:加载js文件

    <script src="{{ url_for('static',filename='js/index.js') }}"></script> 
    

    第三个:加载图片文件

    <img src="{{ url_for('static',filename='images/zhiliao.png') }}" alt="">
    
  • 相关阅读:
    QProgressBar的使用例子
    kube框架结构-一个小型响应式CSS框架
    窗口类型(Widget, Window, Dialog, Desktop, SubWindow等等)
    Qt 之 设置窗口边框的圆角(使用QSS和PaintEvent两种方法)
    十大开源游戏引擎深入比较
    一种通用查询语言的定义与实践
    EF分页问题探讨之 OrderBy
    手把手教你做关键词匹配项目
    git
    Extension+NVelocity
  • 原文地址:https://www.cnblogs.com/songboriceboy/p/13851738.html
Copyright © 2020-2023  润新知