Python WebflaskFlask网站开发

Flask系列:模板

2016-02-11  本文已影响7255人  超net

这个系列是学习《Flask Web开发:基于Python的Web应用开发实战》的部分笔记

虽然可以在视图中直接编写 HTTP 页面的内容,但是这种方式很原始。将与数据库交互的业务逻辑,与生成响应的表现逻辑混在了一起。一方面不适合大型、复杂页面的编写、维护,结构不清晰,另外,由于业务逻辑通常由程序员完成,而表现逻辑由设计师完成,这样双方的工作会互相影响。

@app.route('/')
def index():
    return '<h1>Hello World!</h1>'

flask 支持 MVC 模型,由程序员在视图中完成与数据库的交互——业务逻辑(M),而显示给客户端的页面在模板中定义(V),由设计师完成。

模板是一个包含响应文本的文件(通常是 HTML),其中包含用 占位变量 表示的动态部分, 具体值只在收到具体的请求后,通过上下文才能知道,模板中最主要的是前端技术,HTLM、CSS、JS 等。

模板引擎实现对模板的渲染,就是根据上下文,对模板中的占位变量,用真实值替换,形成最终的响应文件。

模板文件夹

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

模板的调用

flask 使用 jinjia2 模板引擎,为了便于使用,已经集成到 render_template 函数中,可以直接调用。

from flask import Flask, render_template

@app.route('/')
def index():
    return render_template('index.html')    # 注意,是包含 .html 后缀的完整文件名

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

第一个参数是模板的名称,然后是 键/值 对,name=name左边表示模板中的占位符,右边是当前视图中的变量。意思是,将当前视图中变量name的值,赋值给模板中名为name的占位符,用于渲染。

变量

{{ name }}

占位符,告诉模板引擎,这个位置的值从渲染模板时传递的数据字典中获取

支持所有类型,字符串、整型、列表、字典 ......

通过使用过滤器,可以定制 变量的值 显示的效果,比如 大小写。{{ name | 过滤器 }}

过滤器列表

在模板中设置模板变量

{% set name = 'john' %}

控制结构

主要用于改变渲染流程

if...else...endif

判断条件是否符合,并执行相应的语句

用于渲染一组元素

类似函数

定义一个宏,指定宏的名称、参数,调用

{% macro x(y) %}
    ...
{% endmacro %}

{{ x(y) }}

如果需要在多个模板中复用,可以将宏的定义放入一个文件,‘macro.html’

{% macro x(y) %}
    ...
{% endmacro %}

然后导入使用

import 'macro.html' as macro

{{ macro.x(y) }}

如果多个页面的大部分内容相同,可以定义一个母模板,包含相同的内容,然后子模板继承内容,并根据需要进行部分修改

base.html,母模板,其中,用{% block title %}...{% endblock %}定义了可以由子模板替换的区域,title是区块的名称,可以有多个区块

{% block title %}Hello{% endblock %}

在子模板中,声明继承的母模板,然后用{% block title %}...{% endblock %}指定替换哪个区块的内容,并填入自己的内容。子模板中没有指定的区块,默认使用母模板的内容

{% extends "base.html" %}

{% block title %}john{% endblock %}

如果希望能够保留母版的内容,并添加新内容,可以使用super()

{% extends "base.html" %}

{% block title %}
    {{ super() }}
    john
{% endblock %}

模板里面,不能同时有两个{% extends " " %}语句,即使另一个被注释了也不行

如果多个网页中都有一段内容相同,可以将相同的内容放入一个文件中comments.html,通过include导入

{% include 'comments.html' %}

bootstrap

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

一个名为Flask-Bootstrap的 Flask 扩展, 可以简化在程序中集成 Bootstrap 的过程。

安装:

$ pip install flask-bootstrap

初始化

从 flask.ext 命名空间中导入,然后把 程序实例传入构造方法进行初始化。

run.py

from flask.ext.bootstrap import Bootstrap 
# ...
bootstrap = Bootstrap(app)

初始化 Flask-Bootstrap 之后,就可以在程序中使用一个包含所有 Bootstrap 文件的基模板。 这个模板利用 Jinja2 的模板继承机制,让程序扩展一个具有基本页面结构的基模板,其中 就有用来引入 Bootstrap 的元素。

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

{% block title %}Flasky{% endblock %}
{% block navbar %}

{% 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 文件。

virtualenv 环境中,目录为lib/python2.7/site-packages/flask_bootstrap/templates/bootstrap/

基模板中定义了可在衍生模板中重定义的块。block 和 endblock 指令定义的块中的内容可添加到基模板中。

Bootstrap 官方文档是很好的学习资源,有很多可以直接复制粘贴的示例。

自定义错误页面

像常规路由一样,Flask 允许程序使用基于模板的自定义错误页面。最常见的错误代码有两个:404,客户端请求未知页面或路由时显示;500,有未处理的异常时显示。

自定义错误页面

@app.errorhandler(404)
def page_not_found(e):
    return render_template('404.html'), 404

和视图函数一样,错误处理程序也会返回响应。它们还返回与该错误对应的数字状态码。 返回指定的数字状态码似乎没有什么用 ?

url_for 生成连接

模板中可能有去往多个不同页面的链接,例如导航条。

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

为了避免这些问题,Flask 提供了url_for()辅助函数,它可以使用程序URL映射中保存的信息,根据视图名称生成 URL。

例如,对于下面的视图

@app.route('/')
def index():
    return '<h1>Hello World!</h1>'

调用 url_ for('index')得到的结果是/。调用url_for('index', _external=True)返回的则是绝对地址,是http://localhost:5000/

在程序内(模板、视图中)生成连接程序内不同路由的链接时,使用相对地址就足够了,浏览器、程序能够根据当前的 URL 补全。但如果要在浏览器以外生成链接,例如在确认邮件中的链接,则必须使用绝对地址,否则谁也不知道前缀是什么。

使用url_for()生成链接时,将动态部分作为关键字参数传入。例如,

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

url_for ('user', name='john', _external=True) 的返回结果是 http://localhost:5000/user/john

默认 _external 为 False,表示生成相对路径;为 True 时,表示生成绝对路径

函数能将任何额外参数添加到查询字符串中。例如,

url_for('user', name='john', page=2)的返回结果是/user/john/?page=2

对于多层的模板结构,render_template 函数中需要添加从templates目录下文件夹开始的路径信息,render_template('main/index.html'),结构为templates/main/index.html,url_for() 需要用.隔开目录,url_for('main.index.html')

Jinja2

更多jinja2 模板的语法

上一篇下一篇

猜你喜欢

热点阅读