一、视图函数和视图类
1.endpoint简介
endpoint参数是写在注册路由的装饰器中的一个参数,就是给函数取别名 可以通过取得别名获取url, url_for(别名)
2.装饰器注册路由源码分析总结
1.self.add_url_rule(rule, endpoint, f, options)就是注册路由的核心 2.观察_endpoint_from_view_func函数我们可以知道,返回了视图函数的名字给了endpoint赋值 3.methos没有指定会给methods赋默认值('GET',)
3.另一种注册路由的方式--app_url_rule
def add_url_test(): return '实现了add_url方式注册路由' # url 端点 函数地址 app.add_url_rule('/add_url_test/',endpoint='add_demo',view_func=add_url_test)
4.视图类写法
视图类的基本写法
from flask import Flask, views, request, url_for from functools import wraps def login_verify(func): @wraps(func) def wrapper(*args, **kwargs): user_name = request.args.get('user') password = request.args.get('password') if user_name == 'mark' and password == '123': return func(*args,**kwargs) else: return '请登录' return wrapper class CBVTest(views.MethodView): methods = ['GET','POST'] # 指定可以接收的方法有什么 decorators = [login_verify,] # 指定自定义的装饰器 def get(self): print(url_for('cbvtest')) return 'cbv_get' def post(self): return 'cbv_post' app.add_url_rule('/cbvtest',view_func=CBVTest.as_view(name='cbvtest'),endpoint='end_demo')
讲解:
1.首先从flask中导入 views 2.写一个类一定要继承 views.MethodView 3.在类中写methods = ['GET','POST'] 可以指定可接受的请求类型 4.在类中写decorators = [login_verify,]可以指定装饰器,第一个装饰器是最里层函数依次往后包裹 5.在类中写def get(self):用于获取get请求 6.在类中写def post(self):用于获取post请求 7.添加路由的方法使用 app.add_url_rule( '路由',view_func=CBVTest.as_view(name='自定义一个端点名字')) 其原理是CBVTest.as_view(name='自定义一个端点名字')会返回一个函数,name是为这个函数命的名字,可以通过这个函数进行分发请求等操作。
二、模板
1.重定向
http状态码 暂时性重定向 302 永久性重定向 301
从flask模块导入redirect
from flask import Flask,redirect
暂时性重定向(代码示例)
from flask import Flask,redirect
@app.route('/user_info/') def user_info(): name = request.args.get('name') pwd = request.args.get('pwd') if name=='mark' and pwd == '123': return '{}的信息'.format(name) return redirect('/login/') # 可以换成 return redirect(url_for('login')) @app.route('/login/') def login(): return '这是登录页面'
永久性重定向(代码示例)
from flask import Flask,redirect @app.route('/user_info/') def user_info(): name = request.args.get('name') pwd = request.args.get('pwd') if name=='mark' and pwd == '123': return '{}的信息'.format(name) return redirect('/login/', code=301) # 需要返回301状态码给浏览器 @app.route('/login/') def login(): return '这是登录页面'
2.模板引擎
render_template('blog/login.html') #会主动去template文件夹下面找html文件
模板引擎传参:以关键字实参进行传参,可以传多个,也可以传单个,在html页面中通过{{}}进行数据接收展示
注意:templates文件夹和运行文件必须放在同一级
任何位于{{ }}之间的东西是一个会输出到最终文档的静态式
位于{% %}之间的东西表示流程控制语句,如if和for
第一种传参方式(单个传值):
server.py
@app.route('/') def index(): return render_template('index.html',name="mark",age=18) #将name,age值传给index.html页面
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>模板传参</title> </head> <body> {{name}} #mark {{age}} #18 </body> </html>
第二种传值方式(传递参数都放在一个字典中,然后传递字典):
server.py
@app.route('/demo1/') def demo1(): context_dict = {"name":"mark", "age":"mark", "sex":"girl"} return render_template('index.html',context_dict = context_dict)
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>模板传参</title> </head> <body> {{context_dict.name}} {{context_dict.age}} {{context_dict.sex}} </body> </html>
第三种传值方式(打散的字典):
server.py
def demo2(): context_dict = {"name": "mark", "age": "mark", "sex": "girl", "other_info":{"tel":1365, "qq":565656}} return render_template('index.html',**context_dict)
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>模板传参</title> </head> <body> {{name}} {{age}} {{sex}} {{other_info.tel}} {{other_info["qq"]}} </body> </html>
总结:
在视图函数中: 1.render_template传参的时候以关键字实参进行传参。可以传多个,可以用**讲字典打散成关键字实参 在模板中: 1.模板中支持用{{}}接收变量数据 2.如果是字典,可以用.取出key对应的value值。也可以用[]进行取值
3.模板中使用url_for()
在模板中也适用url_for()获取url,使用{{url_for('视图函数名')}},支持翻转查询字符串,支持动态路由翻转,和在视图函数中用法一样
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>模板传参</title> </head> <body> <a href="/info/">正常跳转</a> <a href="{{ url_for('info')}}">urlfor跳转</a> </body> </html>
4.模板中控制语句if
{% if age > 18 %} <p>成年人</p> {% elif age == 18 %} <p>刚刚成年</p> {% else %} <p>未成年</p> {% endif %} #必须要以endif结尾
5.模板中循环语句for循环
{% for country in countrys%} <p>{{ country }}</p> {% else %} <p>没有值</p> {% endfor %}
#如果for内部没有遍历出来内容,那么就会走else分支,反之则不会走
6.使用url_for()加载静态文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>静态文件加载</title> <link rel="stylesheet" href="{{ url_for('static',filename='css/demo.css') }}"> <script src="{{ url_for('static',filename='js/demo.js') }}"></script> </head> <body> <img src="{{ url_for('static',filename='images/1.png') }}"> </body> </html>
三、闪现
Flask 提供了一个非常简单的方法来使用闪现系统向用户反馈信息。闪现系统使得在一个请求结束的时候记录一个信息,
然后在且仅仅在下一个请求中访问这个数据,强调flask闪现是基于flask内置的session的,利用浏览器的session缓存闪现信息。所以必须设置secret_key。
1.简单的在模板中实现获取闪现的信息
server.py
from flask import Flask, flash, redirect, render_template, request, url_for app = Flask(__name__) app.secret_key = 'some_secret' @app.route('/login', methods=['GET', 'POST']) def login(): error = None if request.method == 'POST': if request.form['username'] != 'admin' or request.form['password'] != '123': error = '登录失败' else: flash('恭喜您登录成功') return redirect(url_for('index')) return render_template('login.html', error=error) if __name__ == "__main__": app.run()
注意:这个flash()可以实现在下一次请求时候,将括号内的信息做一个缓存。不要忘记设置secret_key
index.html
{% with messages = get_flashed_messages() %} # 获取所有的闪现信息返回一个列表 {% if messages %} <ul class=flashes> {% for message in messages %} <li>{{ message }}</li> {% endfor %} </ul> {% endif %} {% endwith %} <h1>主页</h1> <p>跳转到登录页面<a href="{{ url_for('login') }}">登录?</a>
四、启动项目
1.pycharm设置启动
2.命令行启动(在控制台输入命令行)
>>set FLASK_APP=flaskr:create_app('development') #启动文件:参数 >>set FlASK_ENV=development #设置环境 >>flask run linux系统下将set换成export
五、蓝图
1.先注册路由 flaskr/auth.py bp = Blueprint('auth', __name__) 这里创建了一个名称为 'auth' 的 Blueprint 。和应用对象一样, 蓝图需要知道是在哪里定义的,因此把 __name__ 作为函数的第二个参数,__name__表示蓝图所在模块。 2.将蓝图注册到app flaskr/__init__.py app.register_blueprint(auth.bp)