标签:
Flask是一个精简的python web框架,没有封装很多功能,而是通过扩展,来实现相应功能
Flask 依赖两个外部库:Werkzeug 和 Jinja2 。 Werkzeug 是一个 WSGI(在 Web 应用和多种服务器之间的标准 Python 接口) 工具集。Jinja2 负责渲染模板。
@app.route(‘/‘)
def hello_world():
return ‘Hello World!‘
Flask 把request 和返回的头信息,body信息,进行了进一步的封装,看起来更接近一个函数实现一个功能,对http请求与响应进一步封装
app = Flask(__name__)@app.route(‘/‘)def hello_world():
导入了 Flask 类。这个类的实例将会是 WSGI 应用程序。
route() 装饰器告诉 Flask 什么样的URL 能触发我们的函数。
首先实例化WSGI应用程序,然后通过装饰器配置url
@app.route(‘/‘) 将url通过WSGI的实例进行处理,也就是接受http请求
解析http请求,响应http请求,封装好的这些功能通过装饰器进行绑定使用,更加方便简明。
作为单独应用启动还是作为模块导入
if __name__ == ‘__main__‘:
app.run()
最后我们用 run() 函数来让应用运行在本地服务器上
外部可访问的服务器
调试模式
如果你启用了调试支持,服务器会在代码修改后自动重新载入,并在发生错误时提供一个相当有用的调试器。
只能不用调试,不能用于生产环境
开启调试可以得到错误信息
路由
变量规则
@app.route(‘/user/<username>‘)def show_user_profile(username):# show the user profile for that userreturn ‘User %s‘ % username@app.route(‘/post/<int:post_id>‘)def show_post(post_id):# show the post with the given id, the id is an integerreturn ‘Post %d‘ % post_id
转换器有下面几种:
int | 接受整数 |
float | 同 int ,但是接受浮点数 |
path | 和默认的相似,但也接受斜线 |
参数看起来很简明,django是通过request.GET.get来获取url里面的参数,或者通过form表单来实现
转换器只接受规定类型的参数,如果不是规定类型的参数,就会报错
唯一 URL / 重定向行为
Flask 的 URL 规则基于 Werkzeug 的路由模块。保证优雅且唯一的 URL。
@app.route(‘/projects/‘)def projects():return ‘The project page‘@app.route(‘/about‘)def about():return ‘The about page‘
输入projects 忘记加 / 后,会自动跳转到加了下划线的正确url上
输入abouts加了 / 后,会报错
构造 URL
接受对应 URL 规则的变量部分的命名参数。
未知变量部分会添加到 URL 末尾作为查询参数。
url_for 第一个参数是对应函数,第二个是对应参数,不存在添加到末尾作为查询参数,存在
作为参数传递给函数
/login?next=//user/John%20Doe
... print url_for(‘login‘, next=‘/‘)... print url_for(‘profile‘, username=‘John Doe‘)
>>> @app.route(‘/login‘)... def login(): pass...>>> @app.route(‘/user/<username>‘)... def profile(username): pass
为什么你要构建 URL 而非在模板中硬编码,也就是说不是直接写出固定的url,而是通过
url_for动态生成url_for
这里有三个绝妙的理由:
- 反向构建通常比硬编码的描述性更好。更重要的是,它允许你一次性修改 URL, 而不是到处边找边改。
- URL 构建会转义特殊字符和 Unicode 数据,免去你很多麻烦。
- 如果你的应用不位于 URL 的根路径(比如,在 /myapplication 下,而不是 / ),url_for() 会妥善处理这个问题。
HTTP 方法
默认情况下,路由只回应 GET 请求,但是通过 route() 装饰器传递 methods 参数可以改变这个行为
@app.route(‘/login‘, methods=[‘GET‘, ‘POST‘])def login():if request.method == ‘POST‘:do_the_login()else:show_the_login_form()
HTTP 方法(也经常被叫做“谓词”)告知服务器,客户端想对请求的页面 做 些什么。下面的都是非常常见的方法:
HEAD浏览器告诉服务器:欲获取信息,但是只关心 消息头 .GET浏览器告知服务器:只 获取 页面上的信息并发给我。这是最常用的方法。
POST浏览器告诉服务器:想在 URL 上 发布 新信息。并且,服务器必须确保 数据已存储且仅存储一次。这是 HTML 表单通常发送数据到服务器的方法。
@app.route(‘/login‘, methods=[‘GET‘, ‘POST‘])def login():if request.method == ‘POST‘:do_the_login()else:show_the_login_form()
静态文件
url_for(‘static‘, filename=‘style.css‘)
模板渲染
情况 1: 模块:
/application.py
/templates
/hello.html
情况 2: 包:
/application
/__init__.py
/templates
/hello.html
同样的方式进行引用,只不过包的格式有设定
from flask import render_template
@app.route(‘/hello/‘)
@app.route(‘/hello/<name>‘)
def hello(name=None):
return render_template(‘hello.html‘, name=name)
@app.route(‘/hello/‘)
@app.route(‘/hello/<name>‘)
def say_hello(name=None):
name = name
return render_template(‘hello.html‘, name=name)
接受参数,处理参数然后传递给前端页面,不知道这里可不可以用locals()
django接受参数用request,处理参数用locals()
前端html当中的引用和django当中相同
<title>Hello from Flask</title>{% if name %}<h1>Hello {{ name }}!</h1>{% else %}<h1>Hello World!</h1>{% endif %}
可以直接用request和session
访问请求数据
与客户端发送给服务器的数据交互至关重要。在 Flask 中由全局的request 对象来提供这些信息
环境作用域:
环境局部变量
Flask 中的某些对象是全局对象,但却不是通常的那种。这些对象实际上是特定环境的局部对象的代理
一个请求传入,Web 服务器决定生成一个新线程( 或者别的什么东西,只要这个底层的对象可以胜任并发系统,而不仅仅是线程)。 当 Flask 开始它内部的请求处理时,它认定当前线程是活动的环境,并绑定当前的应用和 WSGI 环境到那个环境上(线程)
另一种可能是:传递整个 WSGI 环境给 request_context() 方法:
with app.request_context(environ):assert request.method == ‘POST‘
app.request_context(environ):
来进行单元测试
请求对象
from flask import request
@app.route(‘/login‘, methods=[‘POST‘, ‘GET‘])
def login():
error = None
if request.method == ‘POST‘:
if valid_login(request.form[‘username‘],
request.form[‘password‘]):
return log_the_user_in(request.form[‘username‘])
else:
error = ‘Invalid username/password‘
# the code below is executed if the request method
# was GET or the credentials were invalid
return render_template(‘login.html‘, error=error)
request.form 来访问表单中的数据(POST 或 PUT 请求提交的数据)
你可以通过 args 属性来访问 URL 中提交的参数 ( ?key=value ):
searchword = request.args.get(‘q‘, ‘‘)
文件上传
HTML 表单中设置enctype="multipart/form-data" 属性
已上传的文件存储在内存或是文件系统中一个临时的位置
files属性访问它们。每个上传的文件都会存储在这个字典里
它还有一个 save() 方法,这个方法允许你把文件保存到服务器的文件系统上。
from werkzeug import secure_filename
secure_filename(f.filename))
http://docs.jinkan.org/docs/flask/patterns/fileuploads.html#uploading-files
重定向和错误
from flask import abort, redirect, url_for
@app.route(‘/‘)
def index():
return redirect(url_for(‘login‘))
@app.route(‘/login‘)
def login():
abort(401)
this_is_never_executed()
定制错误页面, 可以使用errorhandler() 装饰器:
from flask import render_template
@app.errorhandler(404)
def page_not_found(error):
return render_template(‘page_not_found.html‘), 404
关于响应
视图函数的返回值会被自动转换为一个响应对象。
如果返回值是一个字符串, 它被转换为该字符串为主体的、状态码为 200 OK``的 、 MIME 类型是 ``text/html 的响应对象。
(response, status, headers) 返回的有三个内容
- 如果返回的是一个合法的响应对象,它会从视图直接返回。
- 如果返回的是一个字符串,响应对象会用字符串数据和默认参数创建。
- 如果返回的是一个元组,且元组中的元素可以提供额外的信息。这样的元组必须是(response, status, headers) 的形式,且至少包含一个元素。 status 值会覆盖状态代码, headers 可以是一个列表或字典,作为额外的消息标头值。
- 如果上述条件均不满足, Flask 会假设返回值是一个合法的 WSGI 应用程序,并转换为一个请求对象。
@app.errorhandler(404)
def not_found(error):
return render_template(‘error.html‘), 404
你只需要把返回值表达式传递给 make_response() ,获取结果对象并修改,然后再返回它:
@app.errorhandler(404)
def not_found(error):
resp = make_response(render_template(‘error.html‘), 404)
resp.headers[‘X-Something‘] = ‘A value‘
return resp
escape(session[‘username‘])转义成想要的字符串内容
from flask import Flask, session, redirect, url_for, escape, request
app = Flask(__name__)
@app.route(‘/‘)
def index():
if ‘username‘ in session:
return ‘Logged in as %s‘ % escape(session[‘username‘])
return ‘You are not logged in‘
@app.route(‘/login‘, methods=[‘GET‘, ‘POST‘])
def login():
if request.method == ‘POST‘:
session[‘username‘] = request.form[‘username‘]
return redirect(url_for(‘index‘))
return ‘‘‘
<form action="" method="post">
<p><input type=text name=username>
<p><input type=submit value=Login>
</form>
‘‘‘
@app.route(‘/logout‘)
def logout():
# remove the username from the session if it‘s there
session.pop(‘username‘, None)
return redirect(url_for(‘index‘))
# set the secret key. keep this really secret:
app.secret_key = ‘A0Zr98j/3yX R~XHH!jmN]LWX/,?RT‘
这里提到的 escape() 可以在你模板引擎外做转义(如同本例)。
如何生成强壮的密钥
随机的问题在于很难判断什么是真随机。一个密钥应该足够随机。你的操作系统可以基于一个密钥随机生成器来生成漂亮的随机值,这个值可以用来做密钥:
>>> import os
>>> os.urandom(24)
‘\xfd{H\xe5<\x95\xf9\xe3\x96.5\xd1\x01O<!\xd5\xa2\xa0\x9fR"\xa1\xa8‘
基础知识
标签:
原文地址:http://www.cnblogs.com/wuqingzangyue/p/5749955.html