您好,欢迎访问一九零五行业门户网

2016-01-04-1 flask web 开发(一)_html/css_WEB-ITnose

2016年, 看的第一本书, 作者是 miguel grinberg 安道翻译.
flask 可算是小而精的web开发框架. 自设计伊始就被定义为可扩展的框架, 通过提供基础服务的核心骨架 + 其它扩展功能 实现, 以满足不同人的需求.
其中, werkzeug , jinja2 都是由flask核心开发者开发而成.
该项目地址在 https://github.com/miguelgrinberg/flasky.git
建议使用pip 完成安装:
pip install flask
程序基本结构 下面从 git 中 1a 开始, (tag=1a),
from flask import flaskfrom flask import requestapp =flask(__name__)@app.route('/')def index(): # user_agent user_agent = request.headers.get('user-agent') return 'hello world! this is my flask project. '@app.route('/user/')def user(name): return 'hello, %s!' % nameif __name__ == '__main__': app.run(debug=true)
初始程序 hello.py 定义了 index() , user 两个函数(称之为视图函数), 分别route 产生了两类网页:
localhost:port/ localhost:port/user/foobar 页面会显示对应的 html 内容. 由自身的 python 函数定义. 如不加指定, 则使用端口为5000.
通过运行服务器的脚本主不可以访问了, 由于 hello.py 给出了 main 入口, 因此
$ python hello.py
便可启动服务, 中止服务器进行使用 ^ + c.
这里就会显示只有一级标题的home page了.
index() 函数 返回的是一段html 内容, 还可以返回第2个结果,
return '<h1>hello world! this is my flask project. </h1>', 400
400 就是页面的state code. 后面涉及到定制错误页面时会涉及到.
flask-script 这里只有app.run()方法来定义嗠的启动, 但这样纯在py-script中定义非常不方便, flask-script是flask扩展, 为flask程序添加了命令行解析器. 自带了一组常用选项和自定义命令.
pip install flask-script
封装 & 使用
from flask.ext.script import managermanager = manager(app)... ...... ...if __name__ == __main__: manager.run()
启动形式(usage):
python hello.py shell 用于维护任务和测试, 调试
python hello.py runserver 启动web服务器 其下又可使用以下参数
-t host 或 --host -p port 或 --port --threaded --processes processes --passthrough-errors -d, --no-debug -r --no-reload 模板 templates --- jinja 2 上面的视图函数非常简单, 对于最简单的一类请求来说这就足够, 但一般而言, 请求会改变程序的状态, 这种变化也会在视图函数中产生.
考虑, 是一个用户在网站中的注册行为. 会有一个用户输入的表单(username, useremail, password, confirm password, valid code, ... ) , 服务器接受到用户的请求(带有信息)之后, flask会把请求分发到处理注册机制的视图函数中, 这个视图函数需要访问数据库, 首先看看user是否已经在数据库了, 如果在则返回警告, 如果不在就继续验证密码是否符合规范, ... 直到满足条件生成一个新用户, 添加至数据库. 然后将响应回送至浏览器. 这个流程就涉及到了 业务逻辑 和 表现逻辑 .
两种逻辑的混淆就会大大增加代码的理解负担和维护成本.
模板是一个包含响应文本的文件. 其中用占位的方式表示了动态部分. 具体的值只在请求的context中才会知道. flask使用jinja2这一强大模板引擎.
jinja2 首先看一个最简单的jinja2模板文件, user.html:
hello, {{ name }}!
这个文件中使用 {{ xxx }}} 的方式定义了 name 这一动态变量, 后续要使用 外部渲染的方式进行传值.
from flask import ..., render_template ... @app.route('/user/')def user(name): return render_template('user.html', name=name)
这里再来简单介绍jinja2的变量处理. 先来看支持的变量类型及格式
<h1>hello, {{ name }}!</h1> str
<h1>hello, {{ dict1['key'] }}!</h1> dict
<h1>hello, {{ mylist[3] }}!</h1> list
<h1>hello, {{ obj.somemethod() }}!</h1> function
其次, 若是需要一些变换, 也可以模板文件中来完成修改, 这一操作通过jinja2的 过滤器 实现.
如:
{{ name|capitalize }} 完成首字母大写 {{ name|safe }} 渲染值是不转义 {{ name|upper }} 完成字母大写 {{ name|lower }} 完成字母小写 {{ name|trim }} 完成首尾空格去除 {{ name|striptags }} 渲染之前把值中所有html标签去掉. 转义: 默认情况下, jinja2 会转义所有变量 -- hello... 会被渲染成 '<h1>hello .... , 浏览器能显示这个h1元素, 但不会进行解释. 千万不要在不可信的值上使用safe过滤器, 特别是用户在表单的输入.
完成的过滤器文档在 jinja2文档
控制结构 渲染流程当然也涉及到结构的概念(先后顺序, 条件分支...), 参考下面的例子:
{% if user %} hello, {{ user }}!{% else %} hello, stranger!{% endif %}
除此之外, jinja2还支持宏(macro, 类似于python中的函数), 当涉及到重复渲染时, 可能会用到. 宏以外, 还可以使用 模板的继承.
模板继承 模板继承, 将不同页面中相同的元素抽象成一个block. 这是一个base范例
{% block head %} {% block title %}{% endblock %} - my application {% endblock %} {% block body %} {% endblock %}
这个基模板就有3个block: head, title和body(注: title是嵌套在head之中的), 在继承时, 就可以使用了.
{% extends base.html %}{% block title %}index{% endblock %}{% block head %} {{ super() }} {% endblock %}{% block body %}hello, world!{% endblock %}
框架 - bottstrap bootstrap( http://getbootstrap.com/ ) 是twitter开发的一汞客户端框架, 提供了用户界面组件, 简洁有力, 兼容web浏览器. 但因其不涉及服务器, 服务器使用还要提供 css和js文件的html响应. flask提供了拓展.
flask-bootstrap pip install flask-bootstrap 初始化 from flask.ext.boostrap import bootstrap bootstrap = bootstrap(app)
使用 在模板文件中继承,
{% extends bootstrap/base.html %} ...
从flask-bootstrap中extends了base基模板文件, 从而引入了bootstrap中所有css和js文件.
自定义错误页面 如果用户输入了错误的route 地址, 为了体现更好的体验, 保持完整统一性. 可通过自定义实现.
常见的错误代码有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
404.html
{% extends base.html %}{% block title %}flasky - page not found{% endblock %}{% block page_content %} not found
{% endblock %}
链接 flask提供了url_for()辅助函数, 可以使用程序url映射中保存的信息来生成url.
url_for() 最简单用法是以视图函数名作为参数, 返回对应url. 例如, hello.py 程序中调用 url_for('index') 得到结果是 / 调用 url_for('index', _external=true)返回绝对地址, 这里是 http://localhost:5000
如果生成在浏览器之外使用的链接, 则必须使用绝对地址, 例如: 在电子邮件中发送的注册确认link.
静态文件 web程序不光是由python代码和模板组成, 大多数程序还会涉及静态文件. 如引用的图片, js源码文件和css.
static 对静态文件的引用会被作为一个特殊的route, 即 /staticor/
例如调用 url_for('static', filename='css/style.css', _external=true) 得到结果为 http://localhost:5000/static/css/style.css
默认情况下, flask将会在根目录寻找static的子目录寻找静态文件.
flask-moment 使用web程序处理时间, 考虑时区, 格式化的问题. 有一个使用js开发的优秀客户端开源代码库, 名为 moment.js , 可以实现在浏览器中渲染日期和时间. flask-moment是在此基础的flask拓展, 能把moment.js集成到jinja2中.
pip install flask-moment
初始化
from flask.ext.moment import momentmoment = moment(app)
使用 使用flask-moment渲染时间戳,
the local date and time is {{ moment(current_time).format('lll') }}.
that was {{ moment(current_time).fromnow(refresh=true) }}.

format('lll')根据客户端电脑中的时区和区域设置渲染日期和时间, 参数'l'到'llll'分别对不同的复杂程序. format() 函数还可接触自定义的格式符号.
fromnow() 渲染相对时间戳, 如 2 minute ago, 随着refresh=true的指定, 内容会随着时间推移而更新. 一直待在这样的页面, 会发现这个值是动态变化的.
语言本地化 语言可在模板中选择, 传到lang()函数,
{{ moment.lang('es') }}
其它类似信息

推荐信息