• flask基础


    一.flask是什么?

      Flask是一个使用 Python 编写的轻量级 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2 。

      因为它使用简单的核心,用 extension 增加其他功能。Flask没有默认使用的数据库、窗体验证工具。

    二.知识点

      1.实例化flask对象

    app = Flask(__name__,template_folder='templates',static_url_path='/static')

        2.添加路由的方式

    方式一:
      @app.route('/login')  
      def index():
         return render_template('login.html')
    
    方式二:
      def login():
         return render_template('login.html')
      app.add_url_rule('/login', "n1", login)  #'n1'为别名

      3.添加路由关系

        将url和视图函数封装成一个Rule对象)添加到Flask的url_map字段中(详见)

      4.flask+自定义装饰器(简单登录验证)

     1 from flask import Flask,render_template,request,redirect,session
     2 app = Flask(__name__,template_folder='templates',static_url_path='/static')
     3 app.secret_key = "asdfafsd"  #加盐作用,必须有值
     4 
     5 @app.route('/login',methods=['GET','POST'])
     6 def login():
     7     if request.method == 'GET':
     8         return render_template('login.html')
     9     else:
    10         user = request.form.get('user')
    11         pwd = request.form.get('pwd')
    12         if user == '张良' and pwd == '123':
    13             session['user_info'] = user
    14             return redirect('/index')
    15         else:
    16             return render_template('login.html',msg='用户名或者密码错误!')
    17 
    18 def deco(func):
    19     def _deco(*args,**kwargs):
    20         if not session.get('user_info'):
    21             return redirect('/login')
    22         return func(*args, **kwargs)
    23     return _deco
    24 
    25 @app.route('/index',methods=['GET']) 
    26 @deco  #调用装饰器函数写在路由下面
    27 def index():
    28     return render_template('index.html')
    29 
    30 if __name__ == '__main__':
    31     app.run()
    32 
    33 login.html
    34 <body>
    35     <form method="post">
    36         <p>用户名<input type="text" name="user"></p>
    37         <p>密  码<input type="text" name="pwd"></p>
    38         <input type="submit">{{ msg }}
    39     </form>
    40 </body>
    View Code

      5.请求响应相关

    1 request.form   #POST请求,获取表单内容
    2 request.args   #GET请求,字典形式的,获取url中传过来的键值对
    3 request.querystring  #GET请求,bytes形式的    
    4 request.url #返回当前请求完整的URL
    5 request.base_url #不带参数的URL
    6 request.path #url中的路径部分
    from urllib.parse import urlencode,quote,unquote,make_response
    get_data = request.args  #ImmutableMultiDict([''id':'1','name':'tom'])
    get_dict = get_data.to_dict  #{''id':'1','name':'tom'}
    get_dict['xx] = 18
    url = urlencode(get_dict)  #id=1&name=tom&xx=18
    
    request.files
    obj = request.files['the_file_name']
    obj.save('/var/www/uploads/' + secure_filename(f.filename))
    
    #请求文件中的url中如果有中文,会得到:
        val = "%E6%8A%8A%E5%87%A0%E4%B8%AA"
        解码:
        unquote(val)
    
        #返回更多的内容
    
        response = make_response("xxxx")
        
        response.header['xxx'] = ‘123return response

      5.路由系统

    @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'])
    
    常用路由系统有以上五种,所有的路由系统都是基于一下对应关系来处理:
    
    DEFAULT_CONVERTERS = {
        'default':          UnicodeConverter,
        'string':           UnicodeConverter,
        'any':              AnyConverter,
        'path':             PathConverter,
        'int':              IntegerConverter,
        'float':            FloatConverter,
        'uuid':             UUIDConverter,
    }
    @app.route和app.add_url_rule参数:
     1 rule,                       URL规则
     2             view_func,                  视图函数名称
     3             defaults=None,              默认值,当URL中无参数,函数需要参数时,使用defaults={'k':'v'}为函数提供参数
     4             endpoint=None,              名称,用于反向生成URL,即: url_for('名称')
     5             methods=None,               允许的请求方式,如:["GET","POST"]
     6             
     7 
     8             strict_slashes=None,        对URL最后的 / 符号是否严格要求,
     9                                         如:
    10                                             @app.route('/index',strict_slashes=False),
    11                                                 访问 http://www.xx.com/index/ 或 http://www.xx.com/index均可
    12                                             @app.route('/index',strict_slashes=True)
    13                                                 仅访问 http://www.xx.com/index 
    14             redirect_to=None,           重定向到指定地址
    15                                         如:
    16                                             @app.route('/index/<int:nid>', redirect_to='/home/<nid>')
    17 18                                             def func(adapter, nid):
    19                                                 return "/home/888"
    20                                             @app.route('/index/<int:nid>', redirect_to=func)
    21             subdomain=None,             子域名访问
    22                                                 from flask import Flask, views, url_for
    23 
    24                                                 app = Flask(import_name=__name__)
    25                                                 app.config['SERVER_NAME'] = 'wupeiqi.com:5000'
    26 
    27 
    28                                                 @app.route("/", subdomain="admin")
    29                                                 def static_index():
    30                                                     """Flask supports static subdomains
    31                                                     This is available at static.your-domain.tld"""
    32                                                     return "static.your-domain.tld"
    33 
    34 
    35                                                 @app.route("/dynamic", subdomain="<username>")
    36                                                 def username_index(username):
    37                                                     """Dynamic subdomains are also supported
    38                                                     Try going to user1.your-domain.tld/dynamic"""
    39                                                     return username + ".your-domain.tld"
    40 
    41 
    42                                                 if __name__ == '__main__':
    43                                                     app.run()
    View Code

      URL反向解析

    from flask import Flask, url_for
    def index():
        v = url_for("xxx")
        print(v)
        return "index"
    
    @app.route('/zzz/<int:nid>',endpoint="aaa")  #endpoint是别名
    def zzz(nid):
        v = url_for("aaa",nid=nid)
        print(v)
        return "index2"
    redirect_to:直接重定向,原url有参数时,跳转时也要传参,注意:不用加类型

    6.自定制正则路由匹配
     1 from flask import Flask, views, url_for
     2             from werkzeug.routing import BaseConverter
     3 
     4             app = Flask(import_name=__name__)
     5 
     6 
     7             class RegexConverter(BaseConverter):
     8                 """
     9                 自定义URL匹配正则表达式
    10                 """
    11                 def __init__(self, map, regex):
    12                     super(RegexConverter, self).__init__(map)
    13                     self.regex = regex
    14 
    15                 def to_python(self, value):
    16                     """
    17                     路由匹配时,匹配成功后传递给视图函数中参数的值
    18                     :param value: 
    19                     :return: 
    20                     """
    21                     return int(value)
    22 
    23                 def to_url(self, value):
    24                     """
    25                     使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
    26                     :param value: 
    27                     :return: 
    28                     """
    29                     val = super(RegexConverter, self).to_url(value)
    30                     return val
    31 
    32             # 添加到flask中
    33             app.url_map.converters['regex'] = RegexConverter
    34 
    35 
    36             @app.route('/index/<regex("d+"):nid>')
    37             def index(nid):
    38                 print(url_for('index', nid='888'))
    39                 return 'Index'
    40 
    41 
    42             if __name__ == '__main__':
    43                 app.run()
    44 
    45 #自定制正则路由匹配

      7.模板使用

      和Django使用类似......

      不同之处:

         前端循环字典时,dict.items(),后面的括号需要加;后端传来一个字典,前端可用get.('xxx')取值

      markup:相当于Django的mark_safe;

      template_global() template_filter() (在所有的页面都可以使用)

    1 @app.template_global()
    2 def dd(a1, a2):
    3     return a1 + a2
    4 @app.template_filter()
    5 def pp(a1, a2, a3):
    6     return a1 + a2 + a3
    7 
    8 调用:{{dd(1,2)}}  {{ 1|pp(2,3)}}(用‘|’区分)
    View Code

      宏:只有定义的东西在很多地方去使用的时候才去用它

    1 {% macro input(name, type='text', value=' ') %}
    2     <input type="{{ type }}" name="{{ name }}" value="{{ value }}">
    3 {% endmacro %}
    4 
    5 {{ input('n1') }} 
    View Code

      8.session

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

    • 删除:session.pop('username', None)
     1 from flask import Flask, session, redirect, url_for, escape, request
     2  
     3 app = Flask(__name__)
     4  
     5 @app.route('/')
     6 def index():
     7     if 'username' in session:
     8         return 'Logged in as %s' % escape(session['username'])
     9     return 'You are not logged in'
    10  
    11 @app.route('/login', methods=['GET', 'POST'])
    12 def login():
    13     if request.method == 'POST':
    14         session['username'] = request.form['username']
    15         return redirect(url_for('index'))
    16     return '''
    17         <form action="" method="post">
    18             <p><input type=text name=username>
    19             <p><input type=submit value=Login>
    20         </form>
    21     '''
    22  
    23 @app.route('/logout')
    24 def logout():
    25     # remove the username from the session if it's there
    26     session.pop('username', None)
    27     return redirect(url_for('index'))
    28  
    29 # set the secret key.  keep this really secret:
    30 app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'
    31 
    32 基本使用
    View Code
    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
    自定义session
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    """
    pip3 install redis
    pip3 install flask-session
    
    """
    
    
    from flask import Flask, session, redirect
    from flask.ext.session import Session
    
    
    app = Flask(__name__)
    app.debug = True
    app.secret_key = 'asdfasdfasd'
    
    
    app.config['SESSION_TYPE'] = 'redis'
    from redis import Redis
    app.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 name
    
    
    if __name__ == '__main__':
        app.run()
    
    第三方session
    第三方session

      session配置参数

    - session超时时间如何设置?
                app.config['SESSION_COOKIE_NAME'] = 'session_lvning'
                跟session相关的配置文件
                """
                'SESSION_COOKIE_NAME':                  'session',
                'SESSION_COOKIE_DOMAIN':                None,
                'SESSION_COOKIE_PATH':                  None,
                'SESSION_COOKIE_HTTPONLY':              True,
                'SESSION_COOKIE_SECURE':                False,
                'SESSION_REFRESH_EACH_REQUEST':         True,  #是否每次都更新
                'PERMANENT_SESSION_LIFETIME':           timedelta(days=31)

       9.闪现

      本质:flash是基于session创建的,flash支持往里边放值,只要你取一下就没有了,相当于pop了一下。

     1 from flask import Flask, flash, redirect, render_template, request, get_flashed_messages
     2 app = Flask(__name__)
     3 app.secret_key = 'some_secret'
     4 flag = True
     5 @app.route('/index')
     6 def index1():
     7     global flag
     8     if flag:
     9         flash('登录成功!')
    10         flag=False
    11     return render_template('index.html')
    12 
    13 if __name__ == "__main__":
    14     app.run(port=8600)
    15 
    16 #index.html
    17 <!DOCTYPE html>
    18 <html lang="en">
    19 <head>
    20     <meta charset="UTF-8">
    21     <title>Title</title>
    22 </head>
    23 <body>
    24 {% for msg in get_flashed_messages() %}
    25     <p>{{ msg }}</p>
    26 {% endfor %}
    27 </body>
    28 </html>
    代码实例

      10.flask中通过内置函数实现中间价的效果

    from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request
    app = Flask(__name__)
    app.secret_key ='sdfsdfsdf'
    
    @app.before_request
    def process_request1():
        print('process_request1')
    
    @app.after_request
    def process_response1(response):
        print('process_response1')
        return response
    
    @app.before_request
    def process_request2():
        print('process_request2')
    
    @app.after_request
    def process_response2(response):   #参数也得有
        print('process_response2')
        return response   #必须有返回值
    #注:@app.before_first_request:当程序运行起来,第一个请求来的时候就只执行一次,下次再来就不会在执行了

      11.flask中的CBV模式和FBV模式

     1 def auth(func):
     2             def inner(*args, **kwargs):
     3                 result = func(*args, **kwargs)
     4                 return result
     5             return inner
     6 
     7         class IndexView(views.MethodView):
     8             # methods = ['POST']  #只允许POST请求访问
     9             decorators = [auth,]  #如果想给所有的get,post请求加装饰器,就可以这样来写
    10   
    11             def get(self):   #如果是get请求需要执行的代码
    12                 v = url_for('index')
    13                 print(v)
    14                 return "GET"
    15 
    16             def post(self):  #如果是post请求执行的代码
    17                 return "POST"
    18 
    19         app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))  #name指定的是别名,会当做endpoint使用
    20 
    21         if __name__ == '__main__':
    22             app.run()
    CBV模式
     1 方式一:
     2     @app.route('/index',endpoint='xx')
     3     def index(nid):
     4         url_for('xx',nid=123)
     5         return "Index"
     6 
     7     方式二:
     8     def index(nid):
     9         url_for('xx',nid=123)
    10         return "Index"
    11 
    12     app.add_url_rule('/index',index)
    FBV模式
     
  • 相关阅读:
    greta一些简单实用的字符串匹配
    内存管理
    粒子系统
    资源的后台加载
    GRETA正则表达式模板类库
    便利的开发工具log4cpp快速使用指南
    vc/mfc/vs2005下正则表达式源代码编程/微软greta Regular Expressions
    GRETA库在VS 2005环境下的编译经验
    揭开正则表达式的神秘面纱
    greta简单使用
  • 原文地址:https://www.cnblogs.com/sxh-myblogs/p/8206500.html
Copyright © 2020-2023  润新知