1 flask中登录认证装饰器
1.1 补充:类装饰器
1.1 加在类上的装饰器
1.2 类作为装饰器
1.3 类装饰器装饰类
1.4 有参装饰器
2 配置文件
2.1 flask配置使用方式
2.2 flask的内置配置
3 flask的路由系统
4 CBV基于类的视图
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/' , 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 --》给路由命别名---》可以通过反向解析,通过名字找到路径
4 url_for 做路由反向解析---》需要使用endpoint指定的名字
'''
类装饰器
- 加在类上的装饰器
- 类作为装饰器
# 1 给类加装饰器----》在装饰器中,可以控制对象的产生过程,以及修改对象(给对象加属性或方法)--》增强了对象
# 2 类作为装饰器---》必须要写 __init__ 和 __call__--->原来装饰器在执行被装饰函数之前或之后的代码,都写在__call__中
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)
class Auth():
def __init__(self, func):
print('傻逼')
self.func = func
def __call__(self, *args, **kwargs):
print('执行了')
res = self.func(*args, **kwargs)
return res
@Auth # add=Auth(add) ---> 后续add就是Auth的对象了----》add(1,2)--->Auth类对象()
def add(a, b):
return a + b
res = add(1, 2) # 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 什么是有参装饰器---》之前咱们的装饰器,都不加括号---》如果有参装饰器,装饰器加括号
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
from flask import Flask
app = Flask(__name__)
## 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)
@app.route('/')
def index():
return 'hello sd'
if __name__ == '__main__':
app.run()
{
'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 |
accepts positive floating point values |
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()
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方法---》本质是执行了dispatch_request-->View没有写dispatch--》MethodView写了所以,视图类必须要继承MethodView
## 如果非要继承View,匹配方式,需要自己写
if __name__ == '__main__':
app.run(port=8080)