登录认证装饰器
from flask import Flask, request, render_template, redirect, session, jsonify, url_for app = Flask(__name__) # 如果要用session,必须加这一句 app.secret_key = 'asdfasdfasdf-lqz-justin' USERS = { 1: {'name': '李清照', 'age': 18, 'gender': '男', 'text': "刘亦菲,1987年8月25日出生于湖北省武汉市,华语影视女演员、歌手,毕业于北京电影学院2002级表演系本科", 'img': 'https://img2.woyaogexing.com/2021/10/16/e3ccba623848430ba83209c0621a2256!400x400.jpeg'}, 2: {'name': '彭于晏', 'age': 28, 'gender': '男', 'text': "彭于晏,1982年3月24日出生于中国台湾省澎湖县,毕业于不列颠哥伦比亚大学,华语影视男演员。。。。。。。。", 'img': 'https://img2.woyaogexing.com/2021/10/16/e71aa35728c34313bccb4c371192990f!400x400.jpeg'}, 3: {'name': '迪丽热巴', 'age': 38, 'gender': '女', 'text': "迪丽热巴(Dilraba),1992年6月3日出生于中国新疆乌鲁木齐市,毕业于上海戏剧学院,中国内地影视女演员", 'img': 'https://img2.woyaogexing.com/2021/10/30/6a34146dde2d4f1c832463a5be1ed027!400x400.jpeg'}, 4: {'name': '亚瑟', 'age': 38, 'gender': '男', 'text': "亚瑟,是腾讯手游《王者荣耀》中一名战士型英雄角色,也是《王者荣耀》的新手英雄之一,既可攻又可守", 'img': 'https://img2.woyaogexing.com/2021/10/30/371b2aa7a03c4f53b7b1bc86f877d7d1!400x400.jpeg'}, } def auth(func): def inner(*args, **kwargs): # 判断是否登录---session是全局的直接用即可 username = session.get('username') if username: res = func(*args, **kwargs) return res else: return redirect(url_for('login')) return inner @app.route('/login11', methods=['GET', 'POST'], endpoint='login') def login(): if request.method == 'GET': return render_template('login.html') else: username = request.form.get('username') password = request.form.get('password') if username == 'lqz' and password == '123': # 登录成功,把登录信息,写入到session中 session['username'] = username # 登录成功,重定向到首页 # return redirect('http://www.baidu.com') return redirect('/') else: return render_template('login.html', error='用户名或密码错误') @app.route('/', methods=['GET'], endpoint='index') @auth def index(): return render_template('index.html', user_dict=USERS) @app.route('/detail/<int:pk>', endpoint='detail') @auth def detail(pk): user = USERS.get(pk) return render_template('detail.html', user=user) ''' ###1 只要函数被装饰器装饰器了,以后被装饰的函数,就都叫 inner了 ##2 只要在路由装饰器上加endpoint属性,就可以解决这个问题 ##3 endpoint等同于djagno路由中的name --》给路由命别名---》可以通过反向解析,通过名字找到路径 ## 3 url_for 做路由反向解析---》需要使用endpoint指定的名字 '''
补充
类装饰器 - 加在类上的装饰器 - 类作为装饰器
# 1 加在类上的装饰器---》如果装饰器什么都不写,类用起来跟之前一样 # 2 如果装饰器中对 对象 进行一些操作,只要加了这个装饰器,所有类产生的对象,都会走装饰器inner内的操作 # def auth(func): # def inner(*args, **kwargs): # res = func(*args, **kwargs) # # res 是 Person类的对象 # res.name = '彭于晏' # res.age=99 # return res # # return inner # # # @auth # Person=auth(Person)--->以后Person就变成了 inner # class Person(): # def __init__(self, name): # self.name = name # # # print('------', type(Person)) # Person就变成了 inner,不影响后续使用 # # p = Person('lqz') # p1=Person('sdasfsd') # print(p.name) # print(p.age) ### 2 类作为装饰器 # class Auth(): # def __init__(self, func): # self.func = func # # def __call__(self, *args, **kwargs): # print('我执行了') # res = self.func(*args, **kwargs) # print('执行完了') # return res # # # @Auth # add=Auth(add)--->后续 add 以后就是Auth的对象了--》add(1,2)---》 Auth类对象() # def add(a, b): # return a + b # # # res = add(1, 3) # Auth的对象加括号---》会触发类的————__call__ # print(res) ## 类装饰器装饰类 class Auth(): def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): print('我执行了') res = self.func(*args, **kwargs) print('执行完了') return res @Auth # Person=Auth(Person) class Person: pass p = Person() # Person()---->本质是谁? Auth(Person)()---》触发Auth的__call__ # 1 给类加装饰器----》在装饰器中,可以控制对象的产生过程,以及修改对象(给对象加属性或方法)--》增强了对象 # 2 类作为装饰器---》必须要写 __init__ 和 __call__--->原来装饰器在执行被装饰函数之前或之后的代码,都写在__call__中 # 3 类作为装饰器也可以装饰类 ### 有参装饰器--->额外为被装饰的函数传参数 ### 3 什么是有参装饰器---》之前咱们的装饰器,都不加括号---》如果有参装饰器,装饰器加括号 ## 在装饰器内部,有些动态参数,是通过传参传过来的,就可以使用有参装饰器 def auth(name): def outter(func): def inner(*args, **kwargs): res = func(*args, **kwargs) return res return inner return outter name='彭于晏' @auth(name) # add=auth('lqz')(add) def add(a,b): return a+b
配置文件
Flask配置使用方式
## 1 方式一:直接在app中修改,只能改以下两个 app.debug=True app.secret_key='asdfasdf' ## 2 使用py文件方式---》跟django一样 app.config.from_pyfile('./settings.py') print(app.config) # 就是所有配置信息---》就是django 的 from django.conf import settings print(app.config.get("DEBUG")) print(app.config.get("MYSQL_HOST")) ## 3 类的方式--》以后写出多个类,上线和测试完全分开 app.config.from_object('settings.ProductionConfig') app.config.from_object('settings.DevelopmentConfig') print(app.config.get('DEBUG')) print(app.debug) print(app.debug is app.config.get('DEBUG')) # 4 其他--》了解 # app.config.from_envvar("环境变量名称") # 环境变量的值为python文件名称名称,内部调用from_pyfile方法 # # app.config.from_json("json文件名称") # JSON文件名称,必须是json格式,因为内部会执行json.loads # # app.config.from_mapping({'DEBUG': True}) # 5 配置中心---》apollo和nacos区别 # app.config.from_mapping(config_data)
内置配置
{ 'DEBUG': get_debug_flag(default=False), 是否开启Debug模式 'TESTING': False, 是否开启测试模式 'PROPAGATE_EXCEPTIONS': None, 'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'SECRET_KEY': None, 'PERMANENT_SESSION_LIFETIME': timedelta(days=31), 'USE_X_SENDFILE': False, 'LOGGER_NAME': None, 'LOGGER_HANDLER_POLICY': 'always', 'SERVER_NAME': None, 'APPLICATION_ROOT': None, '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, 'MAX_CONTENT_LENGTH': None, 'SEND_FILE_MAX_AGE_DEFAULT': timedelta(hours=12), 'TRAP_BAD_REQUEST_ERRORS': False, 'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 'JSON_AS_ASCII': True, 'JSON_SORT_KEYS': True, 'JSONIFY_PRETTYPRINT_REGULAR': True, 'JSONIFY_MIMETYPE': 'application/json', 'TEMPLATES_AUTO_RELOAD': None, }
路由系统
''' 1 flask 路由是基于装饰器的 -rule:路径,不能写正则 -methods=['GET','POST] :允许的请求方式 -endpoint: 当前路由的别名---》反向解析用 2 转换器: | `string` | (default) 任意字符串类型,不能带 / | | `int` | 接收正整数 | | `float` | accepts positive floating point values | | `path` | 带 / 的string | | `uuid` | accepts UUID strings | 3 其他写法 @app.route + methods 不写methods 默认只有get [email protected] [email protected] 4 路由系统本质 -装饰器---》本质是 self.add_url_rule(rule, endpoint, f, **options) -self是 Flask(__name__) app对象 -自己注册路由,不使用装饰器 app.add_url_rule('/', view_func=index) app.add_url_rule('/home', view_func=home) 4 其他参数:add_url_rule 本质就是在研究app.route 除了view_func之外的所有参数 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 strict_slashes = None #对URL最后的 / 符号是否严格要求 7 redirect_to = None,#重定向到指定地址 '''
转换器
string | (default) 任意字符串类型,不能带 / |
---|---|
int |
接收正整数 |
float |
接收正小数 |
path |
带 / 的string |
uuid |
accepts UUID strings |
from flask import Flask app = Flask(__name__) app.debug = True ''' 1 flask 路由是基于装饰器的 -rule:路径,不能写正则 -methods=['GET','POST] :允许的请求方式 -endpoint: 当前路由的别名---》反向解析用 2 转换器: | `string` | (default) 任意字符串类型,不能带 / | | `int` | 接收正整数 | | `float` | accepts positive floating point values | | `path` | 带 / 的string | | `uuid` | accepts UUID strings | 3 其他写法 @app.route + methods 不写methods 默认只有get [email protected] [email protected] 4 路由系统本质 -装饰器---》本质是 self.add_url_rule(rule, endpoint, f, **options) -self是 Flask(__name__) app对象 -自己注册路由,不使用装饰器 app.add_url_rule('/', view_func=index) app.add_url_rule('/home', view_func=home) 4 其他参数:add_url_rule 本质就是在研究app.route 除了view_func之外的所有参数 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 strict_slashes = None #对URL最后的 / 符号是否严格要求 7 redirect_to = None,#重定向到指定地址 ''' def index(): return 'he' def home(): return 'html' @app.route('/login', redirect_to='/home') def login(): return 'login' app.add_url_rule('/', view_func=index) app.add_url_rule('/home', view_func=home) if __name__ == '__main__': app.run()
CBV
# cbv:基于类的视图 from flask import Flask, url_for from flask.views import MethodView app = Flask(__name__) app.debug = True ### 1 cbv写法 class LoginView(MethodView): # decorators = [auth] methods = ['get','post'] # 允许的请求方式 def get(self): return 'get' def post(self): print(url_for('login')) return "post" # 注册路由 # LoginView.as_view('login') 参数是别名 app.add_url_rule('/login', view_func=LoginView.as_view('login')) ### 2 cbv加装饰器,直接加在视图类的方法上---》第一个参数必须是self,需要额外处理 # 在类中直接写 decorators = [auth] 按之前装饰器的样子用即可 ### 3 methods的用法 # methods = ['get', 'post'] # 允许的请求方式 ## 4 MethodView继承了View,View中有as_view方法---》本质是执行了dispath_request-->Vie没有写dipatch--》MethodView写了所以,视图类必须要继承MethodView ## 如果非要继承View,匹配方式,需要自己写 if __name__ == '__main__': app.run(port=8080)
标签:__,return,配置文件,Flask,app,CBV,func,装饰,def From: https://www.cnblogs.com/zfq132/p/17833958.html