• python之路_flask框架_flask框架基础(1)


    一、路由系统

      在入门中我们提到了flask框架中的两种路由形式,现在将以第一种形式,详细介绍其中的各个参数。具体参数如下:

    #@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最后的 / 符号是否严格要求,
    '''
    如:
    1、@app.route('/index', strict_slashes=False)访问:http: // www.xx.com / index / 
    或http: // www.xx.com / index均可
    2、@app.route('/index', strict_slashes=True)仅访问http: // www.xx.com / index
    '''
    redirect_to = None                          #重定向到指定地址
    subdomain = None                            #子域名访问

    1、带参数路径

      常见五种路由如下,其中带参数的路由,需要指定参数的类型,不指定类型时即为默认的字符串类型

    @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参数进行传值,这两种的形式的参数都可以在视图函数中进行获得和使用。

    from flask import Flask
    app=Flask(__name__)
    
    @app.route("/index/<int:nid>",defaults={"cid":123})
    def index(nid,cid):
        print(nid,cid)
        return "from index"
    
    if __name__ == '__main__':
        app.run()

     2、url反向解析

      在路由中的endpoint参数即为url的url别名,通过url别名,利用url_for()可以获得反向解析的路径,如下为但参数的反向解析实例,不带参数的路径在反向解析的时候不用给其参数即可。

    from flask import Flask,url_for
    app=Flask(__name__)
    @app.route("/index/<int:nid>",endpoint="xxx")
    def index(nid):
        v=url_for("xxx",nid=nid)                           #带参数形式的反向解析
        print(v)
        return "ok"

    3、重定向参数

      在我们的路由中,我们redirect_to这样一个参数,通过给其配置一个路径,则在请求当前路由的时候,不再访问当前路由所装饰的视图函数,而是访问重定向参数设置对应的路由下视图函数,实例如下:

    from flask import Flask
    app=Flask(__name__)
    @app.route("/old",redirect_to="/new")                 #当访问/old路径时,会重定向到访问/new对应的视图
    def old():
        return "old"
    
    @app.route("/new")
    def new():
        return "new"

    4、子域名访问

    (1)静态域名

      在路由中,有这样的subdomain参数,通过它可以定义我们子域名访问限制,具体实例如下:

    from flask import Flask
    app=Flask(__name__)
    app.config['SERVER_NAME'] = 'bjg.com:5000'   #必须有这样的设置
    @app.route("/index",subdomain="admin")
    def index():
        return "index"

      上例的的解释为:我们想要访问index视图函数,必须要通过admin.bjg.com:5000/index这个路径进行访问才可以访问到,即subdomain参数数限制了我们访问的域名。为了让我的上例测试成功,我们必须对admin.bjg.com域名进行解析,DNS解析一般会先从我们电脑上的文件中进行解析,如果解析不成功就会到公网上解析。为了测试,我们只需要在我们的电脑上进行上述域名的ip对应设置,让测试在电脑上完成。具体步骤如下:

    1、找到路径C:WindowsSystem32driversetc
    2、在此路径的hosts文件中设置:
            127.0.01         admin.bjg.com

    (2)动态域名

      如上设置,我们会把域名限制死,不会很灵活,通过如下的参数的形式,只要能解析成功的域名我们都可以访问,如下:

    from flask import Flask
    app=Flask(__name__)
    app.config['SERVER_NAME'] = 'bjg.com:5000'  #必须有这样的设置
    @app.route("/index",subdomain='<xxx>')
    def index(xxx):
        return "%s.bjg.com" %xxx
    
    '''
    假如有如下形式的域名解析关系,均可以成功访问index视图:
    sss.bjg.com     127.0.0.1
    yyy.bjg.com     127.0.0.1
    zzz.bjg.com     127.0.0.1
    
    访问形式:
    sss.bjg.com :5000/index
    yyy.bjg.com :5000/index
    zzz.bjg.com :5000/index
    '''

     5、自定义正则路由匹配

      具体实现请参考如下实例:

    from flask import Flask,url_for
    
    app = Flask(__name__)
    
    # 定义转换的类
    from werkzeug.routing import BaseConverter
    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
    
    # 添加到converts中
    app.url_map.converters['xxx'] = RegexConverter
    
    # 进行使用
    @app.route('/index/<xxx("d+"):nid>',endpoint='xx')
    def index(nid):
        url_for('xx',nid=123)
        return "Index"
    
    if __name__ == '__main__':
        app.run()
    View Code

    二、视图函数

    1、FBV形式

    from flask import Flask,url_for
    
    app=Flask(__name__)
    # 方式二:
    @app.route("/index/")
    def index():
        return "from index"
    
    
    #方式二:
    def demon():
        return "from demon"
    app.add_url_rule("/demon",demon)
    
    if __name__ == '__main__':
        app.run()

    2、CBV形式

      如下实例,此种视图形式只能使用add_url_rule的形式匹配视图。

    from flask import Flask,views,url_for
    
    app=Flask(__name__)
    def auth(func):
        def inner(*args,**kwargs):
            print("before")
            result=func(*args,**kwargs)
            print("after")
            return result
        return inner
    
    class IndexView(views.MethodView):                                   #必须继承views.MethodView
        methods = ["POST"]                                               #用于指定可以请求的方法,否则请求无法执行post视图
        decorators = [auth,]                                             #用于给视图加装饰器,通过列表加多个
        def get(self):
            url_for("xxx")
            return "GET"
    
        def post(self):
            return "POST"
    
    app.add_url_rule('/index',view_func=IndexView.as_view(name="xxx"))   #name='xxx'为设置的url别名
    
    
    if __name__ == '__main__':
        app.run()

    三、请求与响应

    1、请求request

    # 请求相关信息
            # 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))

      部分实例如下:

    from flask import Flask,request,render_template,jsonify
    from urllib.parse import urlencode
    app=Flask(__name__)
    
    @app.route('/index',endpoint='xxx',methods=["POST","GET"])
    def index():
        if request.method=="POST":
            get_args=request.args
            print(get_args)                 #获得url中参数,如ImmutableMultiDict([('id', '1')])
            get_dict=get_args.to_dict()
            print(get_dict)                 #将其转为字典:{'id': '1'}
            get_dict["xxx"]=18
            url=urlencode(get_dict)
            print(url)                      #结果id=1&xxx=18
    
    
            print(request.query_string)     #结果:b'id=1'
    
            get_form = request.form
            print(get_form)                 #获得form表单中数据,如ImmutableMultiDict([('user', '321'), ('pswd', '321')])
            get_values = request.values
            print(get_values)               #获得即包含url数据又包含form表单中数据
            return jsonify(name="alex",age=18)  #返回json数据形式
    
        return render_template("index.html")
    
    if __name__ == '__main__':
        app.run()

    2、相应response

     # 响应相关信息
            # 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

    四、模板语言

      Flask使用的是Jinja2模板,所以其语法和Django无差别。具体使用见如下实例:

    from flask import Flask,render_template,Markup
    app=Flask(__name__)
    
    #如下方式装饰的方法可以在全局的模板中使用
    
    @app.template_global
    def sb(a,b):
        return a+b
    
    @app.template_filter
    def db(a,b,c):
        return a+b+c
    
    
    def test(a,b):
        return a+b
    
    @app.route('/index')
    def index():
        v1=1111
        v2=[11,22,33]
        v3={"a":1,"b":2}
    
        v4='<input type="text">'
        v5=Markup('<input type="text">')  #Markup等价django的mark_safe
        
        return render_template("index.html",v1=v1,v2=v2,v3=v3,v4=v4,v5=v5,test=test)
    
    if __name__ == '__main__':
        app.run()
    视图
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
        <title>Title</title>
    
    
    </head>
    <body>
    <!--对象-->
    <h1>{{v1}}</h1>
    
    <!--列表循环-->
    {% for i in v2 %}
    <h2>{{i}}</h2>
    {% endfor %}
    <!--列表索引-->
    <h2>{{v2.0}} {{v2.1}} {{v2.2}}</h2>
    <!--字典循环-->
     <ul>
        {% for k,v in v3.items() %}
        <li>{{k}}  {{v}}</li>
        {% endfor %}
     </ul>
    <!--字典索引-->
    <h2>{{v3.a}}</h2>
    <h2>{{v3.get("a")}}</h2>
    <!--标签-->
    <p>{{v4| safe}}</p>
    <p>{{v5}}</p>
    <!--函数-->
    <h1>{{test(23,10)}}</h1>
    
    <!--全局方法@app.template_global-->
    <p>{{sb(1,2)}}</p>
    <!--全局方法@app.template_filter-->
    <p> {{ 1|db(2,3)}}</p>
    
    </body>
    </html>
    模板文件

    五、session

      具体session的设置见如下实例:

    from flask import Flask,session
    
    app = Flask(__name__)
    app.secret_key ='sdfsdfsdf'  #设置session需要设置密钥
    app.config['SESSION_COOKIE_NAME'] = 'session_lvning'  #设置session相关参数
    """
    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)
    """
    
    @app.route('/index',endpoint='xx')
    def index():
        # session本质上操作的是字典,假设session保存在数据库
    
        session['xx2'] = 123
        session['xx3'] = 123
        del session['xx2']
        return "xxx"
    
    if __name__ == '__main__':
        # app.__call__
        app.run()

    六、闪现(flash)

      是一个基于Session实现的用于保存数据的集合,其特点是:使用一次就删除。具体设置和使用实例说明如下:

    from flask import Flask,flash,get_flashed_messages,redirect,url_for
    
    app=Flask(__name__)
    app.secret_key="adfsldgja"                     #flash基于session所以需要设置secret_key
    
    app.route('/user',endpoint="xxx")
    def user():
        msg=get_flashed_messages()                 #取出数据后删除
        print(msg)
        return "ok"
    
    @app.route('/add')
    def add():
        flash("添加成功")                           #存入数据
        return redirect('/user')
    
    if __name__ == '__main__':
        app.run()

    七、扩展

      有如下实例扩展,与django的中间件相似,可以用来处理例如登录验证:

    from flask import Flask
    
    app=Flask(__name__)
    
    
    @app.before_request #无返回值
    def request1():
        print("from request1")
    
    @app.after_request  #有返回值
    def response1(response):
        print("from response1")
        return response
    
    
    @app.before_request
    def request2():
        print("from request2")
    
    
    @app.after_request
    def response2(response):
        print("from response2")
        return response
    
    
    @app.route("/")
    def user():
        print("main")
        return "ok"
    
    
    if __name__ == '__main__':
        app.run()
    
    
    '''
    请求/路径打印结果为:
    from request1
    from request2
    main
    from response2
    from response1
    '''
  • 相关阅读:
    kettle 连接 SQL Server 异常
    Quartz.NET
    过滤器和拦截器
    Spring Web MVC(一)
    Spring(三)之自动装配、表达式
    spring(四)之基于注解(Annotation-based)的配置.md
    Spring(一)之IOC、bean、注入
    Spring(二)之配置.md
    cookie和session详解
    jsp基础与提高(EL、JSTL)
  • 原文地址:https://www.cnblogs.com/seven-007/p/8370850.html
Copyright © 2020-2023  润新知