Flask拾遗总汇1
作者:互联网
一、flask的路由分发方式
路由分发的本质:将url和视图函数封装成一个Rule对象,添加到Flask的url_map字段中
1 方式一: 2 @app.route('/xxxx') # @decorator 3 def index(): 4 return "Index" 5 方式二: 6 def index(): 7 return "Index" 8 app.add_url_rule('/xxx', "n1", index) #n1是别名
二、请求响应相关
1 - request 2 - request.form #POST请求 3 - request.args #GET请求 字典形式的 4 - request.querystring #GET请求,bytes形式的 5 - response 6 - return render_tempalte() 7 - return redirect() 8 - return "" 9 v = make_response(返回值) #吧返回的值包在了这个函数里面 10 - session 11 - 存在浏览器上,并且是加密的 12 - 依赖于:secret_key
三、flask配置文件拾遗(config)
1 方式一: 2 app.config['DEBUG'] = True 3 4 PS: 由于Config对象本质上是字典,所以还可以使用app.config.update(...) 5 6 方式二: 7 app.config.from_pyfile("python文件名称") 8 9 如: 10 settings.py 11 DEBUG = True 12 13 app.config.from_pyfile("settings.py") 14 15 方式三: 16 import os 17 os.environ['FLAKS-SETTINGS'] = 'settings.py' 18 app.config.from_envvar('FLAKS-SETTINGS') 19 20 方法四: 21 见下方from_object用法
1 app.config.from_envvar("环境变量名称") 2 #环境变量的值为python文件名称名称,内部调用from_pyfile方法 3 4 app.config.from_json("json文件名称") 5 #JSON文件名称,必须是json格式,因为内部会执行json.loads 6 7 app.config.from_mapping({'DEBUG':True}) 8 #字典格式
from_object用法:
1 app.config.from_object("python类或类的路径") 2 3 app.config.from_object('pro_flask.settings.TestingConfig') 4 5 settings.py 6 7 class Config(object): 8 DEBUG = False 9 TESTING = False 10 DATABASE_URI = 'sqlite://:memory:' 11 12 class ProductionConfig(Config): 13 DATABASE_URI = 'mysql://user@localhost/foo' 14 15 class DevelopmentConfig(Config): 16 DEBUG = True 17 18 class TestingConfig(Config): 19 TESTING = True 20 21 PS: 从sys.path中已经存在路径开始写 22 23 PS: settings.py文件默认路径要放在程序root_path目录,如果instance_relative_config为True,则就是instance_path目录
current_app用法:
要想在视图函数中获取配置文件的值,都是通过app.config来拿。但是如果视图函数和Flask创建的对象app不在一个模块。就得
导入来拿。可以不用导入。直接导入一个current_app,这个就是当前的app对象,用current_app.config就能查看到了当前app的所有的配置文件
1 from flask import Flask,current_app
1 @app.route('/index',methods=["GET","POST"]) 2 def index(): 3 print(current_app.config) #当前的app的所有配置 4 session["xx"] = "fdvbn" 5 return "index"
四、路由系统参数配置
4.1 可传入参数:
1 @app.route('/user/<username>') #常用的 不加参数的时候默认是字符串形式的 2 @app.route('/post/<int:post_id>') #常用的 #指定int,说明是整型的 3 @app.route('/post/<float:post_id>') 4 @app.route('/post/<path:path>') 5 @app.route('/login', methods=['GET', 'POST'])
4.2 常用路由系统有以上五种,所有的路由系统都是基于一下对应关系来处理:
1 DEFAULT_CONVERTERS = { 2 'default': UnicodeConverter, 3 'string': UnicodeConverter, 4 'any': AnyConverter, 5 'path': PathConverter, 6 'int': IntegerConverter, 7 'float': FloatConverter, 8 'uuid': UUIDConverter, 9 }
五、反向生成URL: url_for
endpoint("name") #别名,相当于django中的name
反向解析需要导入:
1 from flask import Flask, url_for 2 3 @app.route('/index',endpoint="xxx") #endpoint是别名 4 def index(): 5 v = url_for("xxx") 6 print(v) 7 return "index" 8 9 @app.route('/zzz/<int:nid>',endpoint="aaa") #endpoint是别名 10 def zzz(nid): 11 v = url_for("aaa",nid=nid) 12 print(v) 13 return "index2"
@app.route和app.add_url_rule参数:
1 @app.route和app.add_url_rule参数: 2 rule, URL规则 3 view_func, 视图函数名称 4 defaults=None, 默认值,当URL中无参数,函数需要参数时,使用defaults={'k':'v'}为函数提供参数 5 endpoint=None, 名称,用于反向生成URL,即: url_for('名称') 6 methods=None, 允许的请求方式,如:["GET","POST"] 7 8 9 strict_slashes=None, 对URL最后的 / 符号是否严格要求, 10 如: 11 @app.route('/index',strict_slashes=False), 12 访问 http://www.xx.com/index/ 或 http://www.xx.com/index均可 13 @app.route('/index',strict_slashes=True) 14 仅访问 http://www.xx.com/index 15 redirect_to=None, 重定向到指定地址 16 如: 17 @app.route('/index/<int:nid>', redirect_to='/home/<nid>') 18 或 19 def func(adapter, nid): 20 return "/home/888" 21 @app.route('/index/<int:nid>', redirect_to=func) 22 23 subdomain=None, 子域名访问 24 from flask import Flask, views, url_for 25 26 app = Flask(import_name=__name__) 27 app.config['SERVER_NAME'] = 'wxs.com:5000' 28 29 30 @app.route("/", subdomain="admin") 31 def static_index(): 32 """Flask supports static subdomains 33 This is available at static.your-domain.tld""" 34 return "admin.xxx.com" 35 36 #动态生成 37 @app.route("/dynamic", subdomain="<username>") 38 def username_index(username): 39 """Dynamic subdomains are also supported 40 Try going to user1.your-domain.tld/dynamic""" 41 return username + ".your-domain.tld" 42 43 44 if __name__ == '__main__': 45 app.run() 46 所有的域名都得与IP做一个域名解析: 47 如果你想通过域名去访问,有两种解决方式: 48 方式一: 49 1、租一个域名 wxs.lalala 50 2、租一个公网IP 49.8.5.62 51 3、域名解析: 52 wxs.com 49.8.5.62 53 4、吧代码放在49.8.5.62这个服务器上,程序运行起来 54 用户可以通过IP进行访问 55 方式二:如果是自己测试用的就可以用这种方式。先在自己本地的文件中找 56 C:\Windows\System32\drivers\etc 找到HOST,修改配置 57 然后吧域名修改成自己的本地服务器127.0.0.1 58 加上配置:app.config["SERVER_NAME"] = "wxs.com:5000"
域名(subdomain)访问实例:
1 # =============== 子域名访问============ 2 @app.route("/static_index", subdomain="admin") 3 def static_index(): 4 return "admin.bjg.com" 5 6 # ===========动态生成子域名=========== 7 @app.route("/index",subdomain='<xxxxx>') 8 def index(xxxxx): 9 return "%s.bjg.com" %(xxxxx,)
六、flask路由系统的正则匹配配置
扩展Flask的路由系统,让他支持正则,这个类必须这样写,必须去继承BaseConverter
1 from flask import Flask,url_for 2 3 app = Flask(__name__) 4 5 # 定义转换的类 6 from werkzeug.routing import BaseConverter 7 class RegexConverter(BaseConverter): 8 """ 9 自定义URL匹配正则表达式 10 """ 11 12 def __init__(self, map, regex): 13 super(RegexConverter, self).__init__(map) 14 self.regex = regex 15 16 def to_python(self, value): 17 """ 18 路由匹配时,匹配成功后传递给视图函数中参数的值 19 :param value: 20 :return: 21 """ 22 return int(value) 23 24 def to_url(self, value): 25 """ 26 使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数 27 :param value: 28 :return: 29 """ 30 val = super(RegexConverter, self).to_url(value) 31 return val 32 33 # 添加到converts中 34 app.url_map.converters['regex'] = RegexConverter 35 36 # 进行使用 37 @app.route('/index/<regex("\d+"):nid>',endpoint='xx') 38 def index(nid): 39 url_for('xx',nid=123) #反向生成,就会去执行to_url方法 40 return "Index" 41 42 if __name__ == '__main__': 43 app.run()
七、Flask中的CBV模式
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()
八、Flask中的FBV模式
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)
九、Flask中的请求与相应
1 from flask import Flask 2 from flask import request 3 from flask import render_template 4 from flask import redirect 5 from flask import make_response 6 7 app = Flask(__name__) 8 9 10 @app.route('/login.html', methods=['GET', "POST"]) 11 def login(): 12 13 # 请求相关信息 14 # request.method 15 # request.args 16 # request.form 17 # request.values 18 # request.cookies 19 # request.headers 20 # request.path 21 # request.full_path 22 # request.script_root 23 # request.url 24 # request.base_url 25 # request.url_root 26 # request.host_url 27 # request.host 28 # request.files 29 # obj = request.files['the_file_name'] 30 # obj.save('/var/www/uploads/' + secure_filename(f.filename)) 31 32 # 响应相关信息 33 # return "字符串" 34 # return render_template('html模板路径',**{}) 35 # return redirect('/index.html') 36 37 # response = make_response(render_template('index.html')) 38 # response是flask.wrappers.Response类型 39 # response.delete_cookie('key') 40 # response.set_cookie('key', 'value') 41 # response.headers['X-Something'] = 'A value' 42 # return response 43 44 45 return "内容" 46 47 if __name__ == '__main__': 48 app.run()请求与相应详解
1 from flask import Flask,url_for,request,redirect,render_template,jsonify,make_response 2 from urllib.parse import urlencode,quote,unquote 3 app = Flask(__name__) 4 5 @app.route('/index',endpoint='xx') 6 def index(): 7 from werkzeug.datastructures import ImmutableMultiDict 8 ================= 9 # get_data = request.args 10 # get_dict = get_data.to_dict() 11 # get_dict['xx'] = '18' 12 # url = urlencode(get_dict) 13 # print(url) 14 ==================== 15 # print(request.query_string) 16 # print(request.args) 17 ========================== 18 # val = "%E6%8A%8A%E5%87%A0%E4%B8%AA" 19 # print(unquote(val)) #吧上面这样的数据转换成中文 20 # 21 # return "Index" 22 23 # return "Index" 24 # return redirect() 25 # return render_template() 26 # return jsonify(name='alex',age='18') #相当于JsonResponse 27 ======================= 28 response = make_response('xxxxx') #如果是返回更多的值,cookie,headers,或者其他的就可用它 29 response.headers['xxx'] = '123123' 30 return response 31 32 33 if __name__ == '__main__': 34 # app.__call__ 35 app.run()
十、Flask模板语法(jinja2)
template_global和template_filter用法:
调用方式:{{sb(1,2)}} {{ 1|db(2,3)}}
1 @app.template_global() 2 def sb(a1, a2): 3 return a1 + a2 4 5 6 @app.template_filter() 7 def db(a1, a2, a3): 8 return a1 + a2 + a3
十一、session
除请求对象之外,还有一个 session 对象。它允许你在不同请求间存储特定用户的信息。它是在 Cookies 的基础上实现的,并且对 Cookies 进行密钥签名要使用会话,你需要设置一个密钥。
-
设置:session['username'] = 'xxx'
- 删除:session.pop('username', None)
1 from flask import Flask,url_for,session 2 3 app = Flask(__name__) 4 app.secret_key = "sdsfdgdgdgd" 5 app.config['SESSION_COOKIE_NAME'] = 'session_lvning' #设置session的名字 6 7 @app.route('/index/') 8 def index(nid): 9 #session本质上操作的是字典, session是否还有其他方法?与字典方法相同 10 #session的原理:如果下一次访问的时候带着随机字符串,会把session里面对应的 11 # 值拿到内存,假设session保存在数据库,每执行一次链接一次数据库,每次都要时时更新的话 12 # 会非常损耗内存 13 session["xxx"] = 123 14 session["xxx2"] = 123 15 session["xxx3"] = 123 16 session["xxx4"] = 123 17 del session["xxx2"] #在这删除了,真正存储的时候是没有xxx2的 18 return "ddsf" 19 20 if __name__ == '__main__': 21 app.run()
关于session的配置
app.config['SESSION_COOKIE_NAME'] = 'session_lvning'
1 - session超时时间如何设置? 'PERMANENT_SESSION_LIFETIME': timedelta(days=31) 2 以下是跟session相关的配置文件 3 """ 4 'SESSION_COOKIE_NAME': 'session', 5 'SESSION_COOKIE_DOMAIN': None, 6 'SESSION_COOKIE_PATH': None, 7 'SESSION_COOKIE_HTTPONLY': True, 8 'SESSION_COOKIE_SECURE': False, 9 'SESSION_REFRESH_EACH_REQUEST': True, #是否每次都跟新 10 'PERMANENT_SESSION_LIFETIME': timedelta(days=31)
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'View Code
自定义session:
1 pip3 install Flask-Session 2 3 run.py 4 from flask import Flask 5 from flask import session 6 from pro_flask.utils.session import MySessionInterface 7 app = Flask(__name__) 8 9 app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT' 10 app.session_interface = MySessionInterface() 11 12 @app.route('/login.html', methods=['GET', "POST"]) 13 def login(): 14 print(session) 15 session['user1'] = 'alex' 16 session['user2'] = 'alex' 17 del session['user2'] 18 19 return "内容" 20 21 if __name__ == '__main__': 22 app.run() 23 24 session.py 25 #!/usr/bin/env python 26 # -*- coding:utf-8 -*- 27 import uuid 28 import json 29 from flask.sessions import SessionInterface 30 from flask.sessions import SessionMixin 31 from itsdangerous import Signer, BadSignature, want_bytes 32 33 34 class MySession(dict, SessionMixin): 35 def __init__(self, initial=None, sid=None): 36 self.sid = sid 37 self.initial = initial 38 super(MySession, self).__init__(initial or ()) 39 40 41 def __setitem__(self, key, value): 42 super(MySession, self).__setitem__(key, value) 43 44 def __getitem__(self, item): 45 return super(MySession, self).__getitem__(item) 46 47 def __delitem__(self, key): 48 super(MySession, self).__delitem__(key) 49 50 51 52 class MySessionInterface(SessionInterface): 53 session_class = MySession 54 container = {} 55 56 def __init__(self): 57 import redis 58 self.redis = redis.Redis() 59 60 def _generate_sid(self): 61 return str(uuid.uuid4()) 62 63 def _get_signer(self, app): 64 if not app.secret_key: 65 return None 66 return Signer(app.secret_key, salt='flask-session', 67 key_derivation='hmac') 68 69 def open_session(self, app, request): 70 """ 71 程序刚启动时执行,需要返回一个session对象 72 """ 73 sid = request.cookies.get(app.session_cookie_name) 74 if not sid: 75 sid = self._generate_sid() 76 return self.session_class(sid=sid) 77 78 signer = self._get_signer(app) 79 try: 80 sid_as_bytes = signer.unsign(sid) 81 sid = sid_as_bytes.decode() 82 except BadSignature: 83 sid = self._generate_sid() 84 return self.session_class(sid=sid) 85 86 # session保存在redis中 87 # val = self.redis.get(sid) 88 # session保存在内存中 89 val = self.container.get(sid) 90 91 if val is not None: 92 try: 93 data = json.loads(val) 94 return self.session_class(data, sid=sid) 95 except: 96 return self.session_class(sid=sid) 97 return self.session_class(sid=sid) 98 99 def save_session(self, app, session, response): 100 """ 101 程序结束前执行,可以保存session中所有的值 102 如: 103 保存到resit 104 写入到用户cookie 105 """ 106 domain = self.get_cookie_domain(app) 107 path = self.get_cookie_path(app) 108 httponly = self.get_cookie_httponly(app) 109 secure = self.get_cookie_secure(app) 110 expires = self.get_expiration_time(app, session) 111 112 val = json.dumps(dict(session)) 113 114 # session保存在redis中 115 # self.redis.setex(name=session.sid, value=val, time=app.permanent_session_lifetime) 116 # session保存在内存中 117 self.container.setdefault(session.sid, val) 118 119 session_id = self._get_signer(app).sign(want_bytes(session.sid)) 120 121 response.set_cookie(app.session_cookie_name, session_id, 122 expires=expires, httponly=httponly, 123 domain=domain, path=path, secure=secure)
第三方flask-session应用:
session存在在服务端的一个字典里面,session保存起来,取一次里面还是有的,直到你删除之后才没有了
1 from flask import Flask, session, render_template, request, views 2 3 from flask_session import Session 4 from redis import Redis 5 6 app = Flask(__name__) 7 app.default_config() 8 9 app.config["SESSION_TYPE"] = "redis" 10 app.config["SESSION_REDIS"] = Redis(host="127.0.0.1", port=6379, db=0) 11 12 app.templates_auto_reload = True 13 14 # 使用第三方flask-session,封装app这个实例化对象 15 Session(app) 16 17 userinfo = {"user": "alex", "pwd": "123"} 18 19 20 class Login(views.MethodView): 21 methods = ["POST", "GET"] 22 23 def get(self): 24 return render_template("login.html") 25 26 def post(self): 27 user = request.form.get("username") 28 pwd = request.form.get("pwd") 29 30 if user == userinfo["user"] and pwd == userinfo["pwd"]: 31 # 创建session 32 session["user"] = user 33 return "登录成功!" 34 else: 35 return "登录失败!" 36 37 38 app.add_url_rule("/login", endpoint=None, view_func=Login.as_view(name="login")) 39 40 if __name__ == '__main__': 41 app.run()
十二、闪现 : flash
本质:flash是基于session创建的,flash支持往里边放值,只要你取一下就没有了,相当于pop了一下。不仅把值取走,而且把session里的东西去掉
1 from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request 2 app = Flask(__name__) 3 app.secret_key ='sdfsdfsdf' 4 5 @app.route('/users') 6 def users(): 7 # 方式一 8 # msg = request.args.get('msg','') 9 # 方式二 10 # msg = session.get('msg') 11 # if msg: 12 # del session['msg'] 13 # 方式三 14 v = get_flashed_messages() 15 print(v) 16 msg = '' 17 return render_template('users.html',msg=msg) 18 19 @app.route('/useradd') 20 def user_add(): 21 # 在数据库中添加一条数据 22 # 假设添加成功,在跳转到列表页面时,显示添加成功 23 # 方式一 24 # return redirect('/users?msg=添加成功') 25 # 方式二 26 # session['msg'] = '添加成功' 27 # 方式三 28 flash('添加成功') 29 return redirect('/users') 30 31 32 if __name__ == '__main__': 33 app.run(debug=True)
标签:__,return,Flask,app,拾遗,session,总汇,self,def 来源: https://www.cnblogs.com/zhaohaiyu/p/11904676.html