flask基础second,配置文件,路由,模板,请求和响应对象,session使用,闪现

一、flask配置文件

全都可以在app.config里面配置

  # SECRET_KEY:如果使用session,必须配置
  # SESSION_COOKIE_NAME:cookie名字
  # 当使用数据库连接时,由于不是内置的,所以需要配置数据库地址,端口号,也要放到配置文件中,但不是内置的参数

  # flask内置session如何实现的?
      -通过SECRET_KEY加密以后,当做cookie返回给浏览器
      -下次发送请求,携带cookie过来,反解,再放到session中

 

二、路由支持正则

  #1 写一个类class RegexConverter(BaseConverter):,继承BaseConverter

  #2 注册:app.url_map.converters['regex'] = RegexConverter

  # 3 使用:@app.route('/index/<regex("\d+"):nid>')  正则表达式会当作第二个参数传递到类中

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):
        """
        路由匹配时,匹配成功后传递给视图函数中参数的值
        """
        return int(value)

    def to_url(self, value):
        """
        使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
        """
        val = super(RegexConverter, self).to_url(value)
        return val
# 添加到flask中
app.url_map.converters['regex'] = RegexConverter    
@app.route('/index/<regex("\d+"):nid>')
def index(nid):
    print(url_for('index', nid='888'))           #此时nid会传递给to_url里面的value值,自动添加给路由
    return 'Index'

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

 

三、模板

  是jinjia2的模板语言。
    # 之前学的完全一样,for,if, 
    # 模板语言支持函数加括号执行

    # jinjia2模版已经处理xss攻击。如果要正确显示弹框,则处理方式有两种,前端和后端。

        -1 模板层   要渲染的字符串|safe  比如:下的sss
        -2 后端:Markup('<input type="text">')
      # Markup等价django的mark_safe ,
    # extends,include一模一样

#后端
from flask import Flask,render_template,session
app = Flask(__name__)
app.config['DEBUG'] = True

def test(a,b):
    return a+b
def test1():
  return Markup('<input type="text">')

@app.route(
'/index',methods=['GET','POST'],endpoint='ll') def index(): return render_template('index.html',aa='wmt',cc=test,sss='<input type="text">',dd=test1)
) #此时给函数test赋值,然后前端直接调用这个值即可 if __name__ == "__main__": app.run()
#在前端调用函数加括号,也可以传参数
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    
</head>
<body>
{{aa}} {{ cc(1,3) }}

{%for i in ll%}
{%endfor%}

{%include%}

{% if name%}
{% else %}
{% endif %}

{{name|length}} //过滤器

{{sss|safe}}

{{dd()}}
</body> </html>

 

四、request请求对象

  可以获取前端发过来的数据的方法,

 # request.method                提交的方法
    # request.args                     get请求提及的数据
    # request.form                     post请求提交的数据
    # request.values                  post和get提交的数据总和
    # request.cookies                客户端所带的cookie
    # request.headers               请求头
    # request.path                     不带域名,请求路径
    # # request.full_path            不带域名,带参数的请求路径
    # request.url                         带域名带参数的请求路径
    # request.base_url               带域名请求路径
    # request.url_root                 域名
    # request.host_url                域名
    # request.host                      127.0.0.1:500
    # request.files

 

五、响应对象的方法

 直接返回的三板斧:
      # return "字符串"                    直接返回字符串类型
      # return render_template('html模板路径',**{})                       返回模板,后面可以添加其他返回数据或者函数
      # return redirect('/index.html')                     重定向
    # return jsonify({'k1':'v1'})                                   返回 json 数据

 

 cookie相关:
      aa='hello world'                                                   #aa除了可以为字符串外,还可以为其他你想设置cookie的对象,包括模板,如aa=render_template('index.html')
      res=make_response(aa)                                     #需要用make_response包装一下
      res.set_cookie('xxx','lqz')                                     #设置cookie

   res.delete_cookie('key')                                       #删除cookie

      res.headers['X-Something'] = 'A value'                # 往响应头中放东西
      print(type(res))
      from  flask.wrappers import Response
      return res

  例子:
      # 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 'hello'

 

六、导出项目依赖包

  补充:
    varchr :65535个字节的数据
     -utf8:中文2个字节,varchar(300)
     -utf8mb4:3个字节,varchar(300)
    
  快速导出requestment.txt
    pip3 install pipreqs
    pipreqs ./ --encoding=utf-8(一般在Linux上不用加编码方式)

 

七、session的使用及源码

  # 全局导入
  # 视图函数中 session['key']=value
  # 删除:session.pop('key')
  # 取值:session['key']

  内置session源码的类SecureCookieSessionInterface里面的方法:所以自己定义类的时候继承SessionInterface,然后重写下面两个方法。

    # open_session
    # save_session

from flask import Flask,session
app = Flask(__name__)
app.config['DEBUG'] = True

#设置,使用session必须写的设置
app.secret_key='asdqewfqwfq'

#配置session的规则
#app.session_interface = 类()    #可以自己定义一个类,写上满足的规则

@app.route('/',methods=['GET','POST'],endpoint='ll')
def index():
    session['name'] = 'wmt'
    return 'hello'

@app.route('/delete',methods=['GET','POST'])
def delete():
    session.pop('name')       #删除session
    return '删除了session'

@app.route('/order',methods=['GET','POST'])
def order():
    print(session['name'])    #此时设置了session,如果没有session就访问不到
    return 'order'

if __name__ == "__main__":
    app.run(port=8080)       #port=8080此时可以改访问端口

 

八、闪现

  只能取一次,取了之后就没了

  -设置一个值:flash('aaa')
  -取值:get_flashed_message()
  -设置:flash('lqz',category='error1')
  -取值:res=get_flashed_messages(category_filter=['error1'])
  -假设在a页面操作出错,跳转到b页面,在b页面显示a页面的错误信息

from flask import Flask,flash,get_flashed_messages
app = Flask(__name__)
app.config['DEBUG'] = True
app.secret_key ='dewgfewgqrwh'

@app.route('/',methods=['GET','POST'],endpoint='ll')
def index():
    flash('wmt-nb',category='error')      #往某个位置放值,一直放着,只要取了一次,就没了,这里的category是分类的意思。取值时可以直接取分类就可以得出闪现的值
    return 'hello'

@app.route('/order',methods=['GET','POST'])
def order():
    res = get_flashed_messages(category_filter=['error'])    #这里就是取得分类,而不用直接取'wmt-nb'
print(res) #从某个位置出来,只要这里取了一次,下次就没有这个闪现值了 return 'ccccc' if __name__ == "__main__": app.run()

 

九、请求扩展

  类似于django的中间件,请求来与请求走的相关操作

    @app.before_request

      请求来就会触发这个方法,类似于django的process_request,如果有多个,顺序是从上往下。比如下面的例子就是先打印222,再打印111.

@app.before_request
def before(*args,**kwargs):
  print(222)
if request.path=='/login': return None else: name=session.get('user') if not name: return redirect('/login') else: return None
@app.before_request
def before(*args,**kwargs):
  print(111) if request.path=='/login': return None else: name=session.get('user') if not name: return redirect('/login') else: return None

    @app.after_request

      请求走了就会触发,类似于django的process_response,如果有多个,顺序是从下往上执行

@app.after_request
def after(response):return response

    @app.before_first_request

      before_first_request 项目启动起来第一次会走,以后都不会走了,也可以配多个(项目启动初始化的一些操作)

@app.before_first_request
def first():
    print('项目启动,我只执行一次,下次就看不到我了')

    @app.teardown_request  # 用来记录出错日志,每个视图函数只要执行,就会自动执行此方法。此方法需要把调试模式关了

@app.teardown_request
def ter(e):
    print(e)
    print('我是teardown_request ')

    errorhandler绑定错误的状态码,只要访问项目出错后,出错的状态码只要与设定的状态码匹配,那么就会自动执行此方法。返回对应界面

@app.errorhandler(404)
def error_404(arg):
    return render_template('error.html',message='404错误')

    全局标签:在项目任何一个模板都可以使用,且不用在后端视图传值

@app.template_global()
def sb(a1, a2):
    return a1 + a2
#在模板中:{{ sb(
参数1,参数2) }}

    全局过滤器:同上,在项目任何模板都可以使用,且不用在后端视图传值

@app.template_filter()
def db(a1, a2, a3):
    return a1 + a2 + a3
#在模板中{{ 1|db(2,3)}} 就是{{参数1|db(参数2,参数3)}}

注意:

  before_request和after_request,
  注意有多个的情况,执行顺序
  before_request请求拦截后(也就是有return值),response所有都执行

posted @ 2022-03-22 11:35  新入世界的小白  阅读(51)  评论(0编辑  收藏  举报