1. 在commons.py文件中新增一个装饰器类: 注:一定要加入@wraps进行装饰否则,装饰器在给多个函数进行装饰时会报错
python
from functools import wraps
from flask import session, current_app, g
# 定义登陆装饰器,封装用户的登陆数据
def user_login_data(view_func):
@wraps(view_func)
def wrapper(*args, **kwargs):
# 1,从sess1on中取出用户的user1d
user_id = session.get("user_id")
# 2通过user1d取出用户对象
user = None
if user_id:
try:
from info.models import User
user = User.query.get(user_id)
except Exception as e:
current_app.logger.error(e)
# 3.将u5er数据封装到g对象
g.user = user
return view_func(*args, **kwargs)
return wrapper
2.装饰器的使用
python
from flask import current_app, jsonify, render_template, abort, session, g
from . import news_blue
from info import models
from info.utils.response_code import RET
from ...utils.commons import user_login_data
@news_blue.route('/<int:news_id>')
##########自定义装饰器#######################
@user_login_data
def news_detail(news_id):
try:
############################原本的这里的功能被装饰器取代了#############
# # 0,从session中获取到user_id,并根据user_id获取到用户信息
# user_id = session.get('user_id')
# user = models.User.query.get(user_id)
# 1,根据新闻编号,查询新闻对象
try:
news = models.News.query.get(news_id)
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.DBERR, errmsg="获取新闻失败")
# 2. 如果新闻对象不存在直接抛出异常
if not news:
abort(404)
# 获取前6条热点新闻
click_news = models.News.query.order_by(models.News.clicks.desc()).limit(6)
click_news_list = []
for item in click_news:
click_news_list.append(item.to_dict())
# 2.携带数据,渲染页面
data = {
"news_info": news.to_dict(),
#########这里的user直接从g中取出,如果使用装饰包裹时g中是没有user的#########
"user_info": g.user.to_dict() if g.user else '',
"news": click_news_list
}
except Exception as e:
current_app.logger.error(e)
return jsonify(errno=RET.UNKOWNERR, errmsg='未知错误!')
return render_template("news/detail.html", data=data)