一、用工厂方法来实例化应用对象app
def create_app(config_name):
app = Flask(__name__) //实例化启动app
app.config.from_object(config[config_name]) //导入配置信息并动态传入配置信息
db.init_app(app) //关联db和app
Session(app) //把Session对象和app关联
CSRFProtect(app) // csrf保护关联app
此处使用请求钩子,在每次请求之后将csrf_token的值传给前端页面
**此处用来注册蓝图对象
from pro_info.modules.news import news_blue
app.register_blueprint(news_blue)
……
注册模板使用的过滤器
from pro_info.utils.common import do_index_class
app.add_template_filter(do_index_class, 'index_class')
return app
二、每次的请求都需要设置跨站保护,该方法可以使用请求钩子的方法,即每次请求之后执行,这个功能可以设置在实例化应用对象的时候就定义,即放在__init__.py文件中的实例化app对象的工厂方法中
@app.after_request
def after_request(response):
csrf_token = csrf.generate_csrf()
response.set_cookie('csrf_token',csrf_token)
return response
并在前端的ajax中设置请求头
headers:{
X-CSRFToken:getCookie(‘csrf_token’)
}
三、由于很多接口需要判断用户是否在线的情况,对此我们采用的是用装饰器的方式实现这一功能的。
def login_required(f): è 定义一个方法,方便被调用
@functools.wraps(f) è 这是一个python内置的装饰器工具,目的是让被装饰的函数的属性不会被改变
def wrapper(*args,**kwargs):
user_id = session.get('user_id') è 尝试获取用户的登录信息
user = None
if user_id:
try:
user = User.query.get(user_id)
except Exception as e:
current_app.logger.error(e)
g.user = user è 使用引用上下文的g变量来保存用户的信息
return f(*args,**kwargs)
//具体的实现方式是让被装饰的函数的名称在返回wrapper之前赋值给wrapper的__name__ è wrapper.name = f.name
return wrapper
四、统一设置返回的错误页面
由于用户的很多不恰当的操作,或者服务器的原因,导致页面无法显示等错误,我们可以设置指定的错误页面,可以使用
app.errorhandle(code_or_exception) 装饰器来实现这一功能,来达到与用户的更加友好的交互页面,写在__init__文件的工厂方法中
@app.errorhandle(错误码)
@user_login_data
def page_not_found(_):
user = g.user
data = {“user_info”:user.to_dict() if user else None}
return render_template(‘指定的错误页面的模板文件’,data=data)
五、为了更直观的展示后台数据效果,需要添加一些测试用户到数据库中,再目录下新建一个.py文件,复制如下代码直接运行即可
import datetime
import random
from info import db
from info.models import User
from manage import app
def add_test_users():
users = []
now = datetime.datetime.now()
for num in range(0, 10000):
try:
user = User()
user.nick_name = "%011d" % num
user.mobile = "%011d" % num
user.password_hash="pbkdf2:sha256:50000$SgZPAbEj$a253b9220b7a916e03bf27119d401c48ff4a1c81d7e00644e0aaf6f3a8c55829"
user.last_login = now - datetime.timedelta(seconds=random.randint(0, 2678400))
users.append(user)
print(user.mobile)
except Exception as e:
print(e)
# 手动开启一个app的上下文
with app.app_context():
db.session.add_all(users)
db.session.commit()
print('OK')
if name == ‘main’:
add_test_users()