博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flask大全
阅读量:6685 次
发布时间:2019-06-25

本文共 19665 字,大约阅读时间需要 65 分钟。

 

Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后触发Flask框架,开发人员基于Flask框架提供的功能对请求进行相应的处理,并返回给用户,如果要返回给用户复杂的内容时,需要借助jinja2模板来实现对模板的处理,即:将模板和数据进行渲染,将渲染后的字符串返回给用户浏览器。

“微”(micro) 并不表示你需要把整个 Web 应用塞进单个 Python 文件(虽然确实可以 ),也不意味着 Flask 在功能上有所欠缺。微框架中的“微”意味着 Flask 旨在保持核心简单而易于扩展。Flask 不会替你做出太多决策——比如使用何种数据库。而那些 Flask 所选择的——比如使用何种模板引擎——则很容易替换。除此之外的一切都由可由你掌握。如此,Flask 可以与您珠联璧合。

默认情况下,Flask 不包含数据库抽象层、表单验证,或是其它任何已有多种库可以胜任的功能。然而,Flask 支持用扩展来给应用添加这些功能,如同是 Flask 本身实现的一样。众多的扩展提供了数据库集成、表单验证、上传处理、各种各样的开放认证技术等功能。Flask 也许是“微小”的,但它已准备好在需求繁杂的生产环境中投入使用。

1
pip3 install flask
from werkzeug.wrappers import Request, Response@Request.applicationdef hello(request):    return Response('Hello World!')if __name__ == '__main__':    from werkzeug.serving import run_simple    run_simple('localhost', 4000, hello)
werkzeug

一. 基本使用

1
2
3
4
5
6
7
8
9
from
flask
import
Flask
app
=
Flask(__name__)
 
@app
.route(
'/'
)
def
hello_world():
    
return
'Hello World!'
 
if
__name__
=
=
'__main__'
:
    
app.run()

二、配置文件

三、路由系统

  • @app.route('/user/<username>')
  • @app.route('/post/<int:post_id>')
  • @app.route('/post/<float:post_id>')
  • @app.route('/post/<path:path>')
  • @app.route('/login', methods=['GET', 'POST'])

常用路由系统有以上五种,所有的路由系统都是基于一下对应关系来处理:

1
2
3
4
5
6
7
8
9
DEFAULT_CONVERTERS
=
{
    
'default'
:          UnicodeConverter,
    
'string'
:           UnicodeConverter,
    
'any'
:              AnyConverter,
    
'path'
:             PathConverter,
    
'int'
:              IntegerConverter,
    
'float'
:            FloatConverter,
    
'uuid'
:             UUIDConverter,
}
def auth(func):            def inner(*args, **kwargs):                print('before')                result = func(*args, **kwargs)                print('after')                return result        return inner        @app.route('/index.html',methods=['GET','POST'],endpoint='index')        @auth        def index():            return 'Index'        或                def index():            return "Index"        self.add_url_rule(rule='/index.html', endpoint="index", view_func=index, methods=["GET","POST"])        or        app.add_url_rule(rule='/index.html', endpoint="index", view_func=index, methods=["GET","POST"])        app.view_functions['index'] = index        或        def auth(func):            def inner(*args, **kwargs):                print('before')                result = func(*args, **kwargs)                print('after')                return result        return inner        class IndexView(views.View):            methods = ['GET']            decorators = [auth, ]            def dispatch_request(self):                print('Index')                return 'Index!'        app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))  # name=endpoint        或        class IndexView(views.MethodView):            methods = ['GET']            decorators = [auth, ]            def get(self):                return 'Index.GET'            def post(self):                return 'Index.POST'        app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))  # name=endpoint        @app.route和app.add_url_rule参数:            rule,                       URL规则            view_func,                  视图函数名称            defaults=None,              默认值,当URL中无参数,函数需要参数时,使用defaults={
'k':'v'}为函数提供参数 endpoint=None, 名称,用于反向生成URL,即: url_for('名称') methods=None, 允许的请求方式,如:["GET","POST"] strict_slashes=None, 对URL最后的 / 符号是否严格要求, 如: @app.route('/index',strict_slashes=False), 访问 http://www.xx.com/index/ 或 http://www.xx.com/index均可 @app.route('/index',strict_slashes=True) 仅访问 http://www.xx.com/index redirect_to=None, 重定向到指定地址 如: @app.route('/index/
', redirect_to='/home/
') 或 def func(adapter, nid): return "/home/888" @app.route('/index/
', redirect_to=func) subdomain=None, 子域名访问 from flask import Flask, views, url_for app = Flask(import_name=__name__) app.config['SERVER_NAME'] = 'wupeiqi.com:5000' @app.route("/", subdomain="admin") def static_index(): """Flask supports static subdomains This is available at static.your-domain.tld""" return "static.your-domain.tld" @app.route("/dynamic", subdomain="
") def username_index(username): """Dynamic subdomains are also supported Try going to user1.your-domain.tld/dynamic""" return username + ".your-domain.tld" if __name__ == '__main__': app.run()
a.注册路由原理
from flask import Flask, views, url_for            from werkzeug.routing import BaseConverter            app = Flask(import_name=__name__)            class RegexConverter(BaseConverter):                """                自定义URL匹配正则表达式                """                def __init__(self, map, regex):                    super(RegexConverter, self).__init__(map)                    self.regex = regex                def to_python(self, value):                    """                    路由匹配时,匹配成功后传递给视图函数中参数的值                    :param value:                     :return:                     """                    return int(value)                def to_url(self, value):                    """                    使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数                    :param value:                     :return:                     """                    val = super(RegexConverter, self).to_url(value)                    return val            # 添加到flask中            app.url_map.converters['regex'] = RegexConverter            @app.route('/index/
') def index(nid): print(url_for('index', nid='888')) return 'Index' if __name__ == '__main__': app.run()
b. 自定制正则路由匹配

四、模板

1、模板的使用

Flask使用的是Jinja2模板,所以其语法和Django无差别

2、自定义模板方法

Flask中自定义模板方法的方式和Bottle相似,创建一个函数并通过参数的形式传入render_template,如:

    

自定义函数

{
{ww()|safe}}
html
#!/usr/bin/env python# -*- coding:utf-8 -*-from flask import Flask,render_templateapp = Flask(__name__)  def wupeiqi():    return '

Wupeiqi

' @app.route('/login', methods=['GET', 'POST'])def login(): return render_template('login.html', ww=wupeiqi) app.run()
run.py
    
Title {
% macro input(name, type='text', value='') %} {
% endmacro %} {
{ input('n1') }} {
% include 'tp.html' %}

asdf{
{ v.k1}}

其他

注意:Markup等价django的mark_safe

五、请求和响应

from flask import Flask    from flask import request    from flask import render_template    from flask import redirect    from flask import make_response    app = Flask(__name__)    @app.route('/login.html', methods=['GET', "POST"])    def login():        # 请求相关信息        # request.method        # request.args        # request.form        # request.values        # request.cookies        # request.headers        # request.path        # request.full_path        # request.script_root        # request.url        # request.base_url        # request.url_root        # request.host_url        # request.host        # request.files        # obj = request.files['the_file_name']        # obj.save('/var/www/uploads/' + secure_filename(f.filename))        # 响应相关信息        # return "字符串"        # return render_template('html模板路径',**{})        # return redirect('/index.html')        # response = make_response(render_template('index.html'))        # response是flask.wrappers.Response类型        # response.delete_cookie('key')        # response.set_cookie('key', 'value')        # response.headers['X-Something'] = 'A value'        # return response        return "内容"    if __name__ == '__main__':        app.run()
View Code

六、Session

除请求对象之外,还有一个 session 对象。它允许你在不同请求间存储特定用户的信息。它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名要使用会话,你需要设置一个密钥。

  • 设置:session['username'] = 'xxx'

  • 删除:session.pop('username', None)
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 '''        

''' @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'

基本使用
pip3 install Flask-Session                run.py            from flask import Flask            from flask import session            from pro_flask.utils.session import MySessionInterface            app = Flask(__name__)            app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'            app.session_interface = MySessionInterface()            @app.route('/login.html', methods=['GET', "POST"])            def login():                print(session)                session['user1'] = 'alex'                session['user2'] = 'alex'                del session['user2']                return "内容"            if __name__ == '__main__':                app.run()        session.py            #!/usr/bin/env python            # -*- coding:utf-8 -*-            import uuid            import json            from flask.sessions import SessionInterface            from flask.sessions import SessionMixin            from itsdangerous import Signer, BadSignature, want_bytes            class MySession(dict, SessionMixin):                def __init__(self, initial=None, sid=None):                    self.sid = sid                    self.initial = initial                    super(MySession, self).__init__(initial or ())                def __setitem__(self, key, value):                    super(MySession, self).__setitem__(key, value)                def __getitem__(self, item):                    return super(MySession, self).__getitem__(item)                def __delitem__(self, key):                    super(MySession, self).__delitem__(key)            class MySessionInterface(SessionInterface):                session_class = MySession                container = {}                def __init__(self):                    import redis                    self.redis = redis.Redis()                def _generate_sid(self):                    return str(uuid.uuid4())                def _get_signer(self, app):                    if not app.secret_key:                        return None                    return Signer(app.secret_key, salt='flask-session',                                  key_derivation='hmac')                def open_session(self, app, request):                    """                    程序刚启动时执行,需要返回一个session对象                    """                    sid = request.cookies.get(app.session_cookie_name)                    if not sid:                        sid = self._generate_sid()                        return self.session_class(sid=sid)                    signer = self._get_signer(app)                    try:                        sid_as_bytes = signer.unsign(sid)                        sid = sid_as_bytes.decode()                    except BadSignature:                        sid = self._generate_sid()                        return self.session_class(sid=sid)                    # session保存在redis中                    # val = self.redis.get(sid)                    # session保存在内存中                    val = self.container.get(sid)                    if val is not None:                        try:                            data = json.loads(val)                            return self.session_class(data, sid=sid)                        except:                            return self.session_class(sid=sid)                    return self.session_class(sid=sid)                def save_session(self, app, session, response):                    """                    程序结束前执行,可以保存session中所有的值                    如:                        保存到resit                        写入到用户cookie                    """                    domain = self.get_cookie_domain(app)                    path = self.get_cookie_path(app)                    httponly = self.get_cookie_httponly(app)                    secure = self.get_cookie_secure(app)                    expires = self.get_expiration_time(app, session)                    val = json.dumps(dict(session))                    # session保存在redis中                    # self.redis.setex(name=session.sid, value=val, time=app.permanent_session_lifetime)                    # session保存在内存中                    self.container.setdefault(session.sid, val)                    session_id = self._get_signer(app).sign(want_bytes(session.sid))                    response.set_cookie(app.session_cookie_name, session_id,                                        expires=expires, httponly=httponly,                                        domain=domain, path=path, secure=secure)
自定义Session
#!/usr/bin/env python# -*- coding:utf-8 -*-"""pip3 install redispip3 install flask-session"""from flask import Flask, session, redirectfrom flask.ext.session import Sessionapp = Flask(__name__)app.debug = Trueapp.secret_key = 'asdfasdfasd'app.config['SESSION_TYPE'] = 'redis'from redis import Redisapp.config['SESSION_REDIS'] = Redis(host='192.168.0.94',port='6379')Session(app)@app.route('/login')def login():    session['username'] = 'alex'    return redirect('/index')@app.route('/index')def index():    name = session['username']    return nameif __name__ == '__main__':    app.run()
第三方session

 

七、蓝图

蓝图用于为应用提供目录划分:

小型应用程序:

大型应用程序:

其他:

  • 蓝图URL前缀:xxx = Blueprint('account', __name__,url_prefix='/xxx')
  • 蓝图子域名:xxx = Blueprint('account', __name__,subdomain='admin')
    # 前提需要给配置SERVER_NAME: app.config['SERVER_NAME'] = 'wupeiqi.com:5000'
    # 访问时:admin.wupeiqi.com:5000/login.html

八、message

message是一个基于Session实现的用于保存数据的集合,其特点是:使用一次就删除。

from flask import Flask, flash, redirect, render_template, request, get_flashed_messages        app = Flask(__name__)        app.secret_key = 'some_secret'        @app.route('/')        def index1():            messages = get_flashed_messages()            print(messages)            return "Index1"        @app.route('/set')        def index2():            v = request.args.get('p')            flash(v)            return 'ok'        if __name__ == "__main__":            app.run()
View Code

九、中间件

from flask import Flask, flash, redirect, render_template, request app = Flask(__name__)app.secret_key = 'some_secret' @app.route('/')def index1():    return render_template('index.html') @app.route('/set')def index2():    v = request.args.get('p')    flash(v)    return 'ok' class MiddleWare:    def __init__(self,wsgi_app):        self.wsgi_app = wsgi_app     def __call__(self, *args, **kwargs):         return self.wsgi_app(*args, **kwargs) if __name__ == "__main__":    app.wsgi_app = MiddleWare(app.wsgi_app)    app.run(port=9999)
View Code

十、请求扩展

#!/usr/bin/env python# -*- coding:utf-8 -*-from flask import Flask, Request, render_templateapp = Flask(__name__, template_folder='templates')app.debug = True@app.before_first_requestdef before_first_request1():    print('before_first_request1')@app.before_first_requestdef before_first_request2():    print('before_first_request2')@app.before_requestdef before_request1():    Request.nnn = 123    print('before_request1')@app.before_requestdef before_request2():    print('before_request2')@app.after_requestdef after_request1(response):    print('before_request1', response)    return response@app.after_requestdef after_request2(response):    print('before_request2', response)    return response@app.errorhandler(404)def page_not_found(error):    return 'This page does not exist', 404@app.template_global()def sb(a1, a2):    return a1 + a2@app.template_filter()def db(a1, a2, a3):    return a1 + a2 + a3@app.route('/')def hello_world():    return render_template('hello.html')if __name__ == '__main__':    app.run()
View Code
调用方式:{
{sb(1,2)}} {
{ 1|db(2,3)}}

十一、Flask插件

  • WTForms    
  • SQLAchemy
  • 等...    http://flask.pocoo.org/extensions/

 

转载于:https://www.cnblogs.com/llhtjwq/p/8665033.html

你可能感兴趣的文章