flask框架(五)——支持正则写法、模板用法、请求响应、session

如果用正则的话,我们要用自定义的路由。

1导入from werkzeug.routing import BaseConverter
2我先要写一个类,然后继承BaseConverter,然后实现__init__, to_python(self, value),to_url(self, value)  这三个方法
3 app.url_map.converters['随便写'] = RegexConverter
4 我们在路由里面@app.route('/index/<regex1("\d+"):nid>'),regex1是随便写,regex1("正则表达式")
5 regex1("正则表达式")匹配出来的结果,返回to_python,一定要return  (视图函数的参数能接收到to_python的返回值)
6 当我们做反向解析的解析的时候,传递的参数,会传递给to_url,return的结果是拼接到我们路由上

代码示例:

from flask import Flask,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):
        """
        路由匹配时,匹配成功后传递给视图函数中参数nid
        """
        #value就正则匹配出来的结果
        print('value',value,type(value))
        return "asdasdasd"  #返回值返回给视图函数中的参数

    def to_url(self, value):
        """
        使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
        """
        val = super(RegexConverter, self).to_url(value)
        print(val)  #val是传入的nid值
        return val   #返回值用于拼接成路径

app.url_map.converters['regex1'] = RegexConverter
@app.route('/index/<regex1("\d+"):nid>',endpoint="sb")
def index(nid):
    print("nid",nid,type(nid))
    print(url_for('sb', nid='888'))  #/index/888
    return 'Index'

if __name__ == '__main__':
    app.run()

模板

模板传递参数、变量的循环、传递html语言代码并且识别

test1.py


USERS = {
1:{'name':'张三','age':18,'gender':'男','text':"道路千万条"},
2:{'name':'李四','age':28,'gender':'男','text':"安全第一条"},
3:{'name':'王五','age':18,'gender':'女','text':"行车不规范"},
}
def func1(st,st1):
    return Markup(f"<h1>jsaon-gdx{st}{st1}</h1>")

@app.route('/list',methods=['GET'])
def list():
    info=USERS
    return render_template('list.html',info1=info,html="<h1>jsaon-gdx</h1>",html1=func1)

list.html (注意:后台传递参数值是info1,前台接收参数也要写info1)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

</head>
<body>
{% for k,v in info1.items() %}  #后台传递的info1参数
        <tr>
            <td>{{k}}</td>
            <td>{{v.name}}</td>
            <td>{{v['name']}}</td>
            <td>{{v.get('name')}}</td>
            <td><a href="{{url_for('sb',nid=k)}}">查看详细</a></td>
        </tr>
{% endfor %}
{{html|safe}}  #传递的html语句,使用|safe能取消转义,从字符串变成能正常显示的html语法
{{html1("-DSB","-SB")}}  #使用Markup,能传递html语句,并且可以传参

</body>
</html>

注意:Mark等价于django的mark_safe

在html中也能通过url_for反向解析路径,并且能够传参(******)

 test.py

@app.route('/detail/<int:nid>',methods=['GET'],endpoint="sb")
def detail(nid):

    return "ok"

list.html   (在detail视图函数中设置好别名,)

<td><a href="{{url_for('sb',nid=k)}}">查看详细</a></td>  #路由跳转,并且把k值传递给nid

请求响应

 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  get请求提及的数据
        # request.form   post请求提交的数据
        # request.values  post和get提交的数据总和
        # request.cookies  客户端所带的cookie
        # request.headers  请求头
        # request.path     不带域名,请求路径
        # request.full_path  不带域名,带参数的请求路径
        # request.script_root  
        # request.url           带域名带参数的请求路径
        # request.base_url      带域名请求路径
        # request.url_root      域名
        # request.host_url      域名
        # request.host          127.0.0.1:500
        # request.files
        # obj = request.files['the_file_name']
        # obj.save('/var/www/uploads/' + secure_filename(f.filename))

        响应相关信息(4剑客)
        # return "字符串"
        # return render_template('html模板路径',**{})
        # return redirect('/index.html')
        #return jsonify({'k1':'v1'})

        # 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()

session

cookie:存放在客户端的键值对
session:存放在客户端的键值对
token:存放在客户端,通过算法来校验

在使用session之前必须设置一下密钥

app = Flask(__name__)
app.secret_key="askjdaksd"   #随便写

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

到源码app.session_interface这里面看(******)
存session:
1 调用save_session,将我们的session加密的val,读取配置文件['SESSION_COOKIE_NAME']得到key
2 将1中的key,val存储到cookies

取session:
1 获取request里面的cookies,获取里面key,这个key就是['SESSION_COOKIE_NAME'],值就是加密的值
2 对该值进行解密

app.session_interface中save_session的参数(设置cookie的参数)

key, 键
value='', 值
max_age=None, 超时时间 cookie需要延续的时间(以秒为单位)如果参数是\ None`` ,这个cookie会延续到浏览器关闭为止
expires=None, 超时时间(IE requires expires, so set it if hasn't been already.)
path='/', Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问,浏览器只会把cookie回传给带有该路径的页面,这样可以避免将cookie传给站点中的其他的应用。
domain=None, Cookie生效的域名 你可用这个参数来构造一个跨站cookie。如, domain=".example.com"所构造的cookie对下面这些站点都是可读的:www.example.com 、 www2.example.com 和an.other.sub.domain.example.com 。如果该参数设置为 None ,cookie只能由设置它的站点读取
secure=False, 浏览器将通过HTTPS来回传cookie
httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)

session源码执行流程

-save_seesion
    -响应的时候,把session中的值加密序列化放大到了cookie中,返回到浏览器中
-open_session
    -请求来了,从cookie中取出值,反解,生成session对象,以后再视图函数中直接用sessoin就可以了。

代码示例:

from flask import Flask,session

app = Flask(__name__)
app.secret_key="askjdaksd"
app.config['SESSION_COOKIE_NAME']="dsb"

@app.route("/")
def index():
    session['jason']="gdx"
    return "ok"

@app.route("/index1")
def index1():
    print(session['jason'])
    return "ok1"

if __name__ == '__main__':
    app.run()

posted @ 2019-11-12 18:52  只会玩辅助  阅读(321)  评论(0编辑  收藏  举报