flask web开发笔记 -- 模板

业务(business logic 比如插入数据库)和展示逻辑(presentation logic, 比如生成返回)最好分开,展示逻辑可以放置在模板中。模板是一个包含响应文本的文件,用占位符变量表示动态部分。rendering(渲染):把占位符用实际值代替,并返回最终响应字符串。Flask采用模板引擎Jinja2。

模板引擎Jinja2

简单的模板:templates/index.html

<h1>Hello World!</h1>

带参数的模板:templates/user.html

<h1>Hello, {{ name }}!</h1>

渲染模板

默认Flask查找应用的templates子目录寻找模板,现在我们对上一章的hello.py基于模板进行改写:

from flask import Flask, render_template
from flask.ext.script import Manager

app = Flask(__name__)

manager = Manager(app)

@app.route(‘/‘)
def index():
    return render_template(‘index.html‘)

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

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

变量

更多变量示例:

<p>A value from a dictionary: {{ mydict[‘key‘] }}.</p>
<p>A value froma list: {{ mylist[3] }}.</p>
<p>A value froma list, with a variable index: {{ mylist[myintvar] }}.</p>
<p>A value froman object‘s method: {{ myobj.somemethod() }}.</p>

注意上面的列表 {{ mylist[myintvar] }},有名字索引。变量后面还可以添加过滤器,比如首字母转为大写其他的转为小写:Hello, {{ name|capitalize }}。Jinja2中常见的变量过滤器如下:

Filter name Description
safe Renders the value without applying escaping
capitalize Converts the first character of the value to uppercase and the rest to lowercase
lower Converts the value to lowercase characters
upper Converts the value to uppercase characters 
title Capitalizes each word in the value 
trim Removes leading and trailing whitespace from the value
striptags Removes any HTML tags from the value before rendering

默认Jinja2因为安全原因转义所有变量,比如变量的值为‘<h1>Hello</h1>‘,Jinja2就会渲染成‘&lt;h1&gt;Hello&lt;/h1&gt;‘,这样就不会被浏览器解释。注意不要对用户表单输入等可能不安全的代码使用safe。完整的内置过滤器参考

控制结构

  • if语句:
{% if user %}
        Hello, {{ user }}!{% else %}
        Hello, Stranger!{% endif %}
  • for语句:
<ul>
        {% for comment in comments %}
                <li>{{ comment }}</li>
        {% endfor %}</ul>
  • macro
{% 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‘ %}

  • 继承

基类:base.html

<html><head>
        {% block head %}
        <title>{% block title %}{% endblock %} - My Application</title>
        {% endblock %}</head><body>
        {% block body %}
        {% endblock %}</body></html>

block标签定义继承模板可以修改的部分,上面有head , title和body三个可变部分。下面有个继承的子模板:

{% extends "base.html" %}{% block title %}Index{% endblock %}{% block head %}
        {{ super() }}
        <style>
        </style>{% endblock %}{% block body %}<h1>Hello, World!</h1>{% endblock %}

使用Flask-Bootstrap集成Twitter Bootstrap

Bootstrap是来自Twitter的开源框架,它提供了用户界面组件以创造简洁并有吸引力的网页并兼容所有现在的网络浏览器。参考资料:维基百科中文Bootstrap介绍维基百科英文Bootstrap介绍

Bootstrap是客户端框架,服务器只需要提供HTML响应,引用Bootstrap的CSS和JavaScript文件并通过HTML、CSS和JavaScript实例化所需的组件。这些事情很适合在模板中做。需要安装:pip install flask-bootstrap。

下面我们flask-bootstrap基于flask-bootstrap对user.html进行修改:

{% 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 %}

上面模板定义了title , navbar和content三个block。Flask-Bootstrap的base.html提供的block如下:

Block name Description
doc The entire HTML document
html_attribs Attributes inside the <html> tag
html The contents of the <html> tag
head The contents of the <head> tag
title The contents of the <title> tag
metas The list of <meta> tags
styles Cascading stylesheet definitions
body_attribs Attributes inside the <body> tag
body The contents of the <body> tag
navbar User-defined navigation bar
content User-defined page content
scripts JavaScript declarations at the bottom of the document

上面的block很多Flask-Bootstrap自己也在使用,通常不能简单重载,需要调用super():

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

hello.py 修改如下:

from flask import Flask, render_template
from flask.ext.script import Manager
from flask.ext.bootstrap import Bootstrap

app = Flask(__name__)

manager = Manager(app)
bootstrap = Bootstrap(app)

@app.route(‘/‘)
def index():
    return render_template(‘index.html‘)

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

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

现在访问根目录,返回的是普通的文本页面。但是访问/user/username已经展示有初步菜单的bootstrap页面了。

自定义错误页

两种最常见的错误码是404 (找不到页面)和500(有未处理异常)。我们再修改下:hello.py:

from flask import Flask, render_template
from flask.ext.script import Manager
from flask.ext.bootstrap import Bootstrap

app = Flask(__name__)

manager = Manager(app)
bootstrap = Bootstrap(app)

@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

@app.route(‘/‘)
def index():
    return render_template(‘index.html‘)

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

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

响应的模板也基于继承进行了调整:

父模板templates/base.html:

{% 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">
    {% block page_content %}{% endblock %}</div>{% endblock %}

子模板:templates/404.html

{% extends "base.html" %}

{% block title %}Flasky - Page Not Found{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Not Found</h1>
</div>
{% endblock %}

子模板:templates/500.html

{% extends "base.html" %}

{% block title %}Flasky - Internal Server Error{% endblock %}

{% block page_content %}
<div class="page-header">
    <h1>Internal Server Error</h1>
</div>
{% endblock %}

子模板:templates/index.html

{% extends "base.html" %}

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

{% block page_content %}
<div class="page-header">
    <h1>Hello World!</h1>
</div>
{% endblock %}

子模板:templates/user.html

{% extends "base.html" %}

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

{% block page_content %}
<div class="page-header">
    <h1>Hello, {{ name }}!</h1>
</div>
{% endblock %}

链接

url_for()函数可以从根据url映射生成链接地址。比如url_for(‘index‘, _external=True)生成 http://localhost:5000/。动态内容比如:url_for(‘user‘, name=‘john‘, _external=True)生成http://localhost:5000/user/john。url_for(‘index‘, page=2)生成/?page=2。

静态文件

通常会有图片、js文件、css等文件。static表示静态文件,url_for(‘static‘, filename=‘css/styles.css‘, _external=True)对应http://localhost:5000/static/css/styles.css。下面我们在templates/base.html的头部增加了一个图标。

{% extends "bootstrap/base.html" %}{% block title %}Flasky{% endblock %}{% 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 %}{% 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">
    {% block page_content %}{% endblock %}</div>{% endblock %}

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

服务器的时间通常以UTC的格式存在,但是浏览器需要显示本地时间,为此需要一个转换,这个工作可以由浏览器来完成。

安装:pip install flask-moment

Flask-Moment依赖jquery.js和moment.js。Bootstrap已经包含了Bootstrap,moment.js需要在模板中加载,修改templates/base.html:

{% extends "bootstrap/base.html" %}{% block title %}Flasky{% endblock %}{% 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 %}{% 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">
    {% block page_content %}{% endblock %}</div>{% endblock %}{% block scripts %}{{ super() }}{{ moment.include_moment() }}{% endblock %}

修改hello.py:

from datetime import datetime
from flask import Flask, render_template
from flask.ext.script import Manager
from flask.ext.bootstrap import Bootstrap
from flask.ext.moment import Moment

app = Flask(__name__)

manager = Manager(app)
bootstrap = Bootstrap(app)
moment = Moment(app)

@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

@app.route(‘/‘)
def index():
    return render_template(‘index.html‘,
                           current_time=datetime.utcnow())

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

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

再修改:templates/index.html

{% extends "base.html" %}

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

{% block page_content %}
<div class="page-header">
    <h1>Hello World!</h1>
</div>
<p>The local date and time is {{ moment(current_time).format(‘LLL‘) }}.</p>
<p>That was {{ moment(current_time).fromNow(refresh=True) }}.</p>
{% endblock %}

format(‘LLL‘)表示基于时区和本地设置,‘L‘ 到 ‘LLLL表示越来越详细。fromNow()会定期刷新,表示到现在的时间有多久。moment.js中实现了format() , fromNow() , fromTime() , calendar() ,valueOf()和unix(),文档参见[momentjs.com/docs/#/displaying/]。

语言选择:{{ moment.lang(‘es‘) }}。

参考资料

时间: 2024-10-01 04:22:57

flask web开发笔记 -- 模板的相关文章

flask web开发笔记 -- 表单 --待整理

虽然Flask的请求对象给表单处理提供了足够的支持,但也有一些任务繁琐和重复.比如为表单生成HTML代码和验证提交表单数据. Flask-WTF扩展能解决上述问题.它基于wtforms 防止跨站请求伪造 跨站请求伪造(Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法.跟跨网站脚本(XSS)相比,XSS

flask web开发笔记 -- 数据库

关系数据库基于关系,有主键.外键等.它存储数据高效,避免了重复:修改数据方便.缺点是连接的成本过高. NoSQL尽量避免连接,但是增加了数据冗余,修改数据麻烦,不过查询快速. 对于中小型的应用,两者的效率差别不大. python数据库框架 Flask对数据库没有限制,你可以使用MySQL, Postgres, SQLite, Redis, MongoDB或CouchDB等.另外还有数据抽象层SQLAlchemy和MongoEngine等. 选择数据库时需要关注: 易用性:抽象层,比如ORM(ob

flask web开发笔记 -- 快速入门

flask web开发笔记 -- 快速入门 初始化 Flask应用需要创建应用实例. Web服务器通过Web Server Gateway Interface (WSGI)协议把从客户端接收到的请求传递给该对象.应用程序实例是Flask类对象,通常创建如下: from flask import Flask app = Flask(__name__) Flask类的构造函数唯一的参数是应用的主模块名或包名,用于确定应用的根目录.对于大多数应用程序,使用Python的__name__变量即可. 路由

flask web开发笔记 -- 简介

Flask是使用Python编写的轻量级Web应用框架.它基于Werkzeug WSGI工具包和Jinja2 模板引擎. Flask使用BSD授权. Flask基于Python的灵活,为Web开发提供简单的模板.demo:Flask community Flask也被称为微框架,因为它核心简单但扩展性好.Flask没有数据库层.表单验证等第三方已经存在的通用功能.Flask的扩展可以像flask自己实现一样使用这些功能.扩展有ORM(object-relational mappers,对象关系映

Flask之旅《Flask Web开发:基于Python的Web应用开发实战》学习笔记

<Flask Web开发:基于Python的Web应用开发实战> 点击上方的"目录"快速到达哦! 虽然简单的网站(Flask+Python+SAE)已经上线,但只是入门.开发大型网站,系统地学习一遍还是有必要的. 1 虚拟环境 2016-6-8 书上介绍了 virtualenv,每个venv都会拷贝一份packages到项目 /venv目录. virtualenv venv venv\Scripts\activate.bat (venv) $ pip freeze >

《Flask Web开发——基于Python的Web应用开发实践》一字一句上机实践(下)

目录 前言 第8章 用户认证 第9章 用户角色 第10章 用户资料 第11章 博客文章 第12章 关注者 第13章 用户评论 第14章 应用编程接口   前言 第1章-第7章学习实践记录请参见:<Flask Web开发——基于Python的Web应用开发实践>一字一句上机实践(上) 本文记录自己学习<Flask Web开发——基于Python的Web应用开发实践>的第8章-第14章内容.相比于刚开始学习第1-7章内容来说,本部分内容实战性更强,而且在书本上遇到的问题也相对较少,如果

《Flask Web开发:基于Python的Web应用开发实战》pdf 免费下载

<Flask Web开发:基于Python的Web应用开发实战>pdf 免费下载链接: https://u253469.ctfile.com/fs/253469-292665036 第一部分 Flask 简介第1 章 安装 .........................................................................................................................................

《Flask Web开发:基于Python的Web应用开发实战》pdf 完整版免费下载

<Flask Web开发:基于Python的Web应用开发实战>.pdf pdf 完整版免费下载: https://u253469.ctfile.com/fs/253469-292665036 更多电子书下载: http://hadoopall.com/book 内容简介 本书不仅适合初级Web开发人员学习阅读,更是Python程序员用来学习高级Web开发技术的优秀参考书. ? 学习Flask应用的基本结构,编写示例应用: ? 使用必备的组件,包括模板.数据库.Web表单和电子邮件支持: ?

Flask Web开发:基于Python的Web应用开发实战PDF

Flask Web开发:基于Python的Web应用开发实战PDF 百度网盘 链接:https://pan.baidu.com/s/1_Ax_ubMUOwwfoNPUn2mDeQ 提取码:s39f 复制这段内容后打开百度网盘手机App,操作更方便哦 内容简介  · · · · · · 本书不仅适合初级Web开发人员学习阅读,更是Python程序员用来学习高级Web开发技术的优秀参考书. ? 学习Flask应用的基本结构,编写示例应用: ? 使用必备的组件,包括模板.数据库.Web表单和电子邮件支