美文网首页
DAY2-Flask

DAY2-Flask

作者: 捂不暖的石头 | 来源:发表于2017-05-26 03:04 被阅读0次

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

    Jinja2模板引擎

    templates/index.html Jinja2模板
    <h1>Hello World!</h1>
    
    templates/user.html Jinja2模板,包含一个使用变量表示的动态部分
    <h1>Hello, {{name}}!</h1>
    

    渲染模板

    默认情况下,Flask在程序文件夹中的templates子文件夹中寻找模板。

    渲染模板
    from flask import Flask,render_template
    
    app = Flask(__name__)
    
    
    @app.route('/')
    def index():
        return render_template('index.html')
    
    
    @app.route('/user/<name>')
    def user(name):
        return render_template('user.html',name=name)
    

    Flask提供的render_template函数把Jinja2模板引擎集成到了程序中。render_template函数的一个参数是模板的文件名。随后的参数都是键值对,表示模板中变量对应的真实值。
    左边的name表示参数名,就是模板中使用的占位符;右边的`name·是当前作用中的变量,表示同名参数的值。

    变量

    可以使用过滤器修改变量,过滤器添加在变量名之后,中间使用竖线分隔。

    Jinja2变量过滤器
    过滤器名 说明
    safe 渲染值时不转义
    capitalize 把值的首字母转换成大写,其他字母转换成小写
    lower 把值转换成小写形式
    upper 把值转换成大写形式
    title 把值中每个单词的首字母都转换成大写
    trim 把值得首尾空格去掉
    striptags 渲染之前把值中所有的HTML标签都删掉

    出于安全考虑,Jinja2会转义所有变量。

    控制结构

    条件控制语句
    {% if user %}
        Hello, {{user}}!
    {% else %}
        Hello,Stranger!
    {% endif %}
    
    for循环
    <ul>
        {% for comment in comments %}
            <li>{{comment}}</li>
        {% endfor %}
    </ul>
    
    宏(类似于函数)
    {% macro render_comment(comment) %}
        <li>{{comment}}</li>
    {% endmacro %}
    
    <ul>
        {% for comment in comments %}
            {{render_comment(comment)}}
        {% endfor %}
    </ul>
    
    导入模板
    {% import 'macros.html' as macros %}
    <ul>
        {% for comment in comments %}
            {{macros.render_comment(comment)}}
        {% endfor %}
    </ul>
    
    
    写入单独的文件,避免重复
    {% include 'common.html' %}
    
    模板继承——基模板
    <html>
    <head>
        {% block head %}
        <title>{% block title %}{% endblock %} - My Application</title>
        <% endblock %}
    </head>
    <body>
        {% block body %}
        {% endblock %}
    </body>
    </html>
    
    
    模板继承——衍生模板
    {% extends "base.html" %}
    {% block title %}Index{% endblock %}
    {% block head %}
        {{ super()}}
        <style>
        </style>
    {% endblock %}
    {% block body %}
    <h1>Hello,world!</h1>
    {% endblock %}
    

    extends指令声明这个模板衍生自base.html。注意新定义的head块,在基模板中其内容不是空的,所有使用super()获取原来的内容。

    Flask-Bootstrap

    安装

    pip install flask-bootstrap
    

    Flask扩展一般都在创建程序实例时初始化。

    初始化Flask-Bootstrap
    from flask_bootstrap import Bootstrap
    
    bootstrap = Bootstrap(app)
    
    使用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="incon-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 %}
    
    浏览地址:       http://127.0.0.1:5000/user/Dave
    
    Flask-Bootstrap 基模板中定义的块
    块名 说明
    doc 整个HTML文档
    html_attribs <html>标签中的内容
    html <html>标签中的内容
    head <head>标签中的内容
    title <title>标签中的内容
    metas 一组<meta>标签
    styles 层叠样式表定义
    body_attribs <body>标签的属性
    body <body>标签中的内容
    navbar 用户定义的导航条
    content 用户定义的页面内容
    scripts 文档底部的JavaScript声明

    如果要在衍生模板中添加新的JavaScript文件,需要这么定义scripts块:

    {% block scripts %}
    {{super()}}
    <script type="text/javascript" src="my-script.js"></script> 
    {% endblock %}
    

    自定义错误页面

    最常见的错误代码

    404    客户端请求未知页面或路由时显示
    500    有未处理的异常时显示
    
    自定义错误页面
    @app.errorhandler(404)
    def page_not_found(e):
        return render_template('404.html'), 404
    
    
    @app.errorhandler(500)
    def internal_server_error(e):
        return render_template('500.html'), 500
    
    包含导航条的程序基模板
    {% 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="incon-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">
        {% block page_content %}{% endblock %}
    </div>
    {% endblock %}
    
    
    使用模板继承机制自定义404错误页面
    {% extends "base.html" %}
    {% block title %}Flasky - Page Not Found{% endblock %}
    {% block page_content %}
    <div class="page-header">
        <h1>Not Found</h1>
    </div>
    {% endblock %}
    
    
    使用模板机制简化页面模板
    {% extends "base.html" %}
    {% block title %}Flasky{% endblock %}
    {% block page_content%}
    <div class="page-header">
        <h1>Hello,{{name}}!</h1>
    </div>
    {% endblock %}
    
    

    链接

    url_for()辅助函数,可以使用程序URL映射中保存的信息生成URL。
    url_for()函数最简单的用法是以视图函数名(或者app.add_url_route()定义路由时使用的端点名)作为参数,返回对应的URL。 使用url_for()生成动态地址时,将动态部分作为关键字参数传入。 传入url_for()`的关键字参数不仅限于动态路由中的参数。函数能将任何额外参数添加到查询字符串中。

    静态文件

    默认设置下,Flask在程序根目录中名为static的子目录中寻找静态文件。

    定义收藏夹图片
    {% block head %}
    {{super()}}
    <link rel="shortcut icon" href="{{url_for('static',filename='favicon.ico')}}" type="image/x-icon">
    <link rel="icon" href="{{url_for('static',filename='favicon.ico')}}" type="image/x-icon">
    {% endblock %}
    

    图标的声明会插入head块的末尾。

    使用Flask-Moment本地化日期和时间

    pip install flask-moment
    
    初始化Flask-Moment
    from flask_moment import Moment
    moment = Moment(app)
    
    引入 moment.js库
    {% block scripts %}
    {{super()}}
    {{moment.include_moment()}}
    {% endblock %}
    
    初始化Flask-Moment
    from datetime import datetime
    
    
    @app.route('/')
    def index():
        return render_template('index.html',current_time=datetime.utcnow())
    
    使用Flask-Moment渲染时间戳
    {% extends "base.html" %}
    <p>The local date and time is {{moment(current_time).format('LLL') }} .</p>
    <p>That was {{moment(current_time).fromNow(refresh=True) }} .</p>
    
    

    format('LLL')根据客户端电脑中的时区和区域设置渲染日期和时间。参数决定了渲染的方式,LLLLL分别对应不同的复杂度。format()函数还可接受自定义的格式说明符。
    第二行中的fromNow()渲染相对时间戳,而且会随着时间的推移自动刷新显示的时间。
    Flask-Moment 渲染的时间戳可实现多种语言的本地化。语言可在模板中选择,把语言代码传给lang()函数即可。

    {{moment.lang('es')}}
    

    相关文章

      网友评论

          本文标题:DAY2-Flask

          本文链接:https://www.haomeiwen.com/subject/qwzzxxtx.html