1、类视图
1.1映射转换方式
除了@route(’/’)给函数添加装饰器映射路由外,还可以通过app.add_url_rule(’/’,view_func=func)来映射,类视图就要用add_url_rule来注册映射
from flask import Flask,url_for
app = Flask(__name__)
@app.route('/')
def index1():
print(url_for('hanshu')) # 也可以在add_url_rule中通过endpoint定义函数名
return '首页'
def index2():
return '详情页面'
app.add_url_rule('/list/', endpoint='hanshu',view_func=index2)
if __name__ == '__main__':
app.run(debug=True)
1.2标准类视图
标准类视图是继承自flask.views.View,并且在子类中必须实现dispatch_request方法,这个方法类似于视图函数,也要返回一个基于Response或者其子类的对象
from flask import Flask,views
app = Flask(__name__)
class IstView(views.View):
def dispatch_request(self):
# 调用demo4
x = self.demo4()
# 必须重写它,如果不重写会抛出异常
return '视图页%s'%x
def demo4(self):
return 'hahah'
app.add_url_rule('/profile/',endpoint='list',view_func=IstView.as_view('change_name'))
# 用来endpoint就会改映射的函数名称,endpoint优于as_view显示
# 就相当于起一个别名,方便url_for反转的时候调用,endpoint取得名字不能重复,否则会报错
if __name__ == '__main__':
app.run(debug=True)
案例1:使用标准类视图返回json类型的字符串
class JsonView(views.View):
def get_response(self):
# raise NotImplementedError() # 可以去重写父类中的方法,使得页面更整洁
return {'username':'beiyue'}
def dispatch_request(self):
response = self.get_response()
return jsonify(response)
app.add_url_rule('/ll/',view_func=JsonView.as_view('hh'))
if __name__ == '__main__':
app.run(debug=True)
案例2:返回公共的变量
from flask import render_template,Flask
class BaseView(views.View):
def __init__(self):
# 工作上会把公共变量写在基类中,页面通过继承的关系来实现调用
super(BaseView, self).__init__()
self.context = {
'username': 'beiyue'
}
class LoginView(BaseView):
def dispatch_request(self):
return render_template('login.html',**self.context)
class RegeditView(BaseView):
def dispatch_request(self):
return render_template('regedit.html',**self.context)
app.add_url_rule('/login/',view_func=LoginView.as_view('pp'))
app.add_url_rule('/regedit/',view_func=RegeditView.as_view('uu'))
if __name__ == '__main__':
app.run(debug=True)
1.3基于调度方法的视图
flask.views.MethodView,对每个HTTP方法执行不同的函数
案例1:实现登录逻辑
class LoginView(views.MethodView):
# 当客户端通过get方法进行访问的时候执行的函数
def get(self):
return render_template("login.html")
# 当客户端通过post方法进行访问的时候执行的函数
def post(self):
email = request.form.get("email")
password = request.form.get("password")
if email == 'xx@qq.com' and password == '111111':
return "登录成功!"
else:
return "用户名或密码错误!"
# 通过add_url_rule添加类视图和url的映射,并且在as_view方法中指定该url的名称,方便url_for函数调用
app.add_url_rule('/myuser/',view_func=LoginView.as_view('loginview'))
案例2:自定义登录验证装饰器
在视图函数中用装饰器直接加上@就可以装饰,在类中用装饰器的时候要通过decorators=[login_requires],必须这样写,才能存储装饰器。以后每次调用这个类视图的时候,就会执行这个装饰器
from flask import session,request
def login_required(func):
def wrapper(*args,**kwargs):
if not session.get("user_id"):# 或者request.args.get('user_id')
return 'auth failure'
return func(*args,**kwargs) # 或者返回请先登录的字符串
return wrapper
class UserView(views.MethodView):
decorators = [login_required]
...
2、蓝图和子域名
2.1蓝图
如果项目比较大的话,将所有的视图函数或者类视图放在同一个文件,这显然不是一个合理的结构,会显得冗余,也不好维护,而蓝图可以优雅的帮我们实现分区管理。将不同功能分别写一个模块,通过app.register_blueprint()方法将这个蓝图注册进url映射中,从主入口进入就方便维护了(避免主入口臃肿,功能用不同模块实现,导入注册引用)
2.2寻找静态文件
默认不设置任何静态文件路径,Jinja2会在项目的static文件夹中寻找静态文件。也可以设置其他的路径,在初始化蓝图的时候,Blueprint这个构造函数,有一个参数static_folder可以指定静态文件的路径,在配置完蓝图后,还有一个需要注意的地方是如何在模板中引用静态文件。在模板中引用蓝图,应该要使用蓝图名+.+static来引用
2.3寻找模板文件
跟静态文件一样,默认不设置任何模板文件的路径,将会在项目的templates中寻找模板文件。也可以设置其他的路径,在构造函数Blueprint中有一个template_folder参数可以设置模板的路径bp = Blueprint('admin',__name__,url_prefix='/admin',template_folder='templates')
2.4在蓝图中使用url_for返回路由
用url_for生成蓝图的url,使用的格式是:蓝图名称+.+视图函数名称。比如要获取admin这个蓝图下的index视图函数的urlurl_for('admin.index')
,蓝图名称就是创建蓝图时传入的第一个参数,没有什么实际的意义
2.5子域名
定义:子域名就是一个域名的关联域名,就比如一个网站叫做beiyue.com可以定义一个子域名为cms.beiyue.com作为管理beiyue.com的子域名网址,
配置:win想要f在lask中支持子域名要进行两个配置,mac也一样,目录在/etx/hosts中,去C:\Windows\System32\drivers\etc中写入两句话
使用:在蓝图中定义名称和子域名,必须一致才可以访问,在主入口中注册后要配置flask配置信息为定义的域名,因为flask不认识IP子域名地址
说明:改了后对本机没有影响,127.0.0.1还是代表本机地址,只不过在修改了flask配置文件的项目中用不了127.0.0.1和localhost,要用修改的配置信息即beiyue.com才能进行访问