Flask学习2:模板引擎

模板引擎

模板引擎

说明:

模板文件就是按照特定规则书写的一个负责展示效果的html文件;模板引擎就是提供了特定规则的解释和替换的功能。

Jinja2:

在Flask中使用的就是该模板引擎,由Flask核心开发组人员开发。

jinja2使用

1.准备工作,目录结构

project/
manage.py  # 项目的启动控制文件
    templates/  # 所有的模板文件

2.渲染模板文件

在templates下创建一个模板文件(hello.html),内容如下:

<h1>渲染字符串</h1>

​模板渲染

@app.route('/')
def index():
    # return '模板引擎测试'

    # 渲染模板文件
    # return render_template('hello.html')

    # 渲染字符串
    return render_template_string('<h1>渲染字符串</h1>')

3.使用变量

​在templates下创建一个模板文件(hello.html),内容如下:

<h1>Nice,{{ g.name }}</h1>


模板渲染

@app.route('/var/')
def va():
    # g对象,在模板使用中不需要分配
    g.name = 'Nian'
    # return render_template('hello.html',)
    # return render_template_string('<h1>{{ name }}</h1>',)
    return render_template_string('<h1>{{ g.name }}</h1>')

4.使用函数

​在模板文件中可以使用特定的函数,对指定的变量处理后再显示,用法如下:

<h1>Nice,{{ g.name | upper }}</h1>

​常用函数

5.流程控制

​分支语句(if-else)

    {% if name %}
        <h1>{{ name }}</h1>
    {% else %}
        <h1>Stranger</h1>
    {% endif %}


@app.route('/control/')
def control():
    # return render_template('if-else.html', name = 'Nian')
    return render_template('if-else.html')

​循环语句

    <ol>
        {% for i in range(1, 5) %}
            <li>{{ i }}</li>
        {% endfor %}
    </ol>

6.文件包含

​include1.html

# include.html
<h1>Include 1</h1>

{% include 'include2.html' %}


# include2.html
<!DOCTYPE html>
<html>
<head>
    <meta>
    <title>被包含</title>
</head>
<body>
    include 2
</body>
</html>

7.宏的使用

    {# 定义宏 #}
    {% macro show_name(name) %}
        <h1>Hello, {{ name }}</h1>
    {% endmacro %}


    {# 调用宏 #}
    {{ show_name(name) }}


    # 宏的使用
    @app.route('/macro/')
    def macro():
        # return render_template('macro.html', name = 'Nian')
        return render_template('macro2.html', name = 'dandan')

  说明:
      采用类似Python中的函数的形式进行定义和调用,可以把特定功能的内容定义为一个宏,哪里使用哪里调用即可。

8.模板继承

# parents.html
<!DOCTYPE html>
<html>
<head>
    <meta>
    <title>{% block title %}父级标题{% endblock %}</title>
</head>
<body>
    {% block body %}
        默认内容
    {% endblock %}
</body>
</html>


# children.html
{% extends 'parents.html ' %}

{% block title %}
    丹丹测试
{% endblock %}

{% block body %}
    这是模板继承   这是=》{{ super() }}
{% endblock %}

flask-bootstrap

1.安装

pip install flask-bootstrap

2.使用:

from flask_bootstrap import Bootstrap

# 创建实例
app = Flask(__name__)
bootstrap = Bootstrap(app)

3.测试模板文件boot.html

{# 继承自bootstrap模板 #}
{% extends 'bootstrap/base.html' %}

{% block title %}
    用户注册
{% endblock %}

{% block content %}
    <div>
        欢迎丹丹来注册
    </div>
{% endblock %}

4.bootstrap继承模板base.html中定义的block

使用bootstrap时,发现重写block后原来的显示效果消失,可能是忘了调用super

定义项目基础模板

1.说明:

一个项目中,很多页面都很相似,只有细微的差别,如果每个页面都定制,势必会有大量的重复代码。为了简化这种重复工作,通常我们会为项目定制一个基础模板,让它继承自bootstrap,其他页面继承自该基础模板,只需稍微定制即可。

2.步骤

1.从bootcss.com复制一个导航条
2.将container-fluid改为container
3.根据需要,定制显示内容

3.基础模板文件base.html

{% extends 'bootstrap/base.html' %}

{% block title %}
    丹丹的标题
{% endblock %}

{% block navbar %}
    <nav>
  <div>
    <!-- Brand and toggle get grouped for better mobile display -->
    <div>
      <button data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
        <span>Toggle navigation</span>
        <span></span>
        <span></span>
        <span></span>
      </button>
      <a>首页</a>
    </div>

    <!-- Collect the nav links, forms, and other content for toggling -->
    <div>
      <ul>
        <li><a>Link <span>(current)</span></a></li>
        <li><a>Link</a></li>
        <li>
          <a data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown <span></span></a>
          <ul>
            <li><a>Action</a></li>
            <li><a>Another action</a></li>
            <li><a>Something else here</a></li>
            <li></li>
            <li><a>Separated link</a></li>
            <li></li>
            <li><a>One more separated link</a></li>
          </ul>
        </li>
      </ul>
      <form>
        <div>
          <input>
        </div>
        <button>Submit</button>
      </form>
      <ul>
        <li><a>Link</a></li>
        <li>
          <a data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown <span></span></a>
          <ul>
            <li><a>Action</a></li>
            <li><a>Another action</a></li>
            <li><a>Something else here</a></li>
            <li></li>
            <li><a>Separated link</a></li>
          </ul>
        </li>
      </ul>
    </div><!-- /.navbar-collapse -->
  </div><!-- /.container-fluid -->
</nav>
{% endblock %}


{# 定制内容 #}
{% block content %}
    <div>
        {# 这里可以为弹出内容显示预留位置 #}
        {% block page_content %}
            默认内容
        {% endblock %}
    </div>
{% endblock %}

错误页面定制

1.添加视图函数

# 错误页面定制
@app.errorhandler(404)
def error(e):
    return render_template('404.html')

2.定制404.html

{% extends 'base.html' %}

{% block title %}
    出错了
{% endblock %}

{% block content %}
    <h1>找不见了吧@_@</h1>
{% endblock %}

回顾url_for函数

1.根据视图函数名反向构造路由地址,路由需要的直接构造,多出来的参数以GET方式 传递

2.若需要构造完整的外部链接,需要添加_extenal=True参数

3.通常网站中的点击链接都是url_for构造的

<li><aregister') }}">注册</a></li>

加载静态资源

1.flask框架中静态资源的默认目录为static,项目目录如下:

project/
    manage.py  # 启动控制文件
    static/  # 存放静态资源
    templates/  # 存放模板文件

2.加载网站图标

{# 加载收藏夹的图标 #}
{% block head %}
    {{ super }}
    <linkstatic', filename = 'bg.png') }}">
{% endblock %}

3.静态资源加载

# manage.py
# 加载静态文件
@app.route('/source/')
def source():
    return render_template('static.html')

# static.html
{% block styles %}
    {{ super() }}
    <linkstatic', filename = 'css.css') }}">
{% endblock %}

4.设置本地日期和时间

# base.html
{#引入moment.js类#}
{% block scripts %}
    {{ super() }}
    {{ moment.include_moment() }}
{% endblock %}



# manage.py
# 使用Flask-Monment本地化日期和时间
from datetime import datetime
@app.route('/testtime/')
def testtime():
    return render_template('testtime.html', current_time = datetime.utcnow())


# testtime.html
  {% block content %}
    <p>The local date and time is {{ moment(current_time).format('LLL') }}</p>
{% endblock %}

5.表单

# maange.py
from flask import Flask, render_template, session, redirect, url_for
from flask_script import Manager
from flask_bootstrap import Bootstrap
from wtforms import SubmitField, StringField, IntegerField
from wtforms.validators import Required
from flask_wtf import Form

# 实例化对象
app = Flask(__name__)
bootstrap = Bootstrap(app)
manager = Manager(app)
app.config['SECRET_KEY'] = 'idandan'

class PersonInfo(Form):
    name = StringField('Name: ', validators=[Required()])
    age = IntegerField('age: ', validators=[Required()])
    submit = SubmitField('Submit')

@app.route('/', methods=['GET', 'POST'])
def index():
    name = None
    age = None
    form = PersonInfo()

    if form.validate_on_submit():
        session['name'] = form.name.data
        session['age'] = form.age.data
        return redirect(url_for('index'))
        # name = form.name.data
        # age = form.age.data
        # form.name.data = ''
        # form.age.data = ''  # ? 不能清空数据???
    # return render_template('personInfo.html', form = form, name = session.get('name'), age = session.get('age'))
    return render_template('personInfo.html', form = form)

if __name__ == '__main__':
    manager.run()



# personInfo.html
{% import 'bootstrap/wtf.html' as wtf %}

{% block title %}
    Form
{% endblock %}

{% block content %}
{#    <h1>#}
{#        Nice,#}
{#        {% if name %}#}
{#            {{ name }}, your age is {{ age }}?#}
{#        {% else %}#}
{#            Stranger!#}
{#        {% endif %}#}
{#    </h1>#}

    <h1>
        Nice,
        {% if session.get('name') %}
            {{ session.get('name') }}, your age is {{ session.get('age') }}?
        {% else %}
            Stranger!
        {% endif %}
    </h1>

    {{ wtf.quick_form(form) }}

{% endblock %}
标签:Flask 发布于:2019-10-21 13:48:44