cbv的使用
from flask import Flask
from flask.views import MethodView
app = Flask(__name__)
# 写一个类 继承 MethodView
class Getview(MethodView):
# 函数名就是请求方法
def get(self):
return '我是get请求'
def post(self):
return '我是post请求'
# 2 注册路由
# Getview.as_view('user')必须加一个字符串---》是路由的别名
# endpoint 和 as_view(name= 路由别名),以谁为准?
# 读源码后,知道了,以 endpoint 为准
# 如果endpoint 没传--》endpoint是 view_func.__name__ 视图函数的名字 ,别名就是函数名
# 如果endpoint 没传,as_view(name= 路由别名)也没传---》去视图函数名字-->视图函数都是:view
# as_view(name= 路由别名) 有什么用? 把view的名字改为了,你传入的字符串名
app.add_url_rule('/user', 'user', Getview.as_view('user'))
if __name__ == '__main__':
app.run(debug=True)
模板语法
from flask import Flask, jsonify, render_template
from markupsafe import Markup
app = Flask(__name__, template_folder='temp')
# app = Flask(__name__, template_folder='./temp') # 自己创建文件夹之后 路径要注意
app.debug = True
@app.route('/')
def index():
# 1 字符串
# 2 字典
user = {'name': 'lqz', 'age': 19}
# 3 函数
def add(a, b):
return a + b
a='<a href="">点我看美女</a>'
a=Markup(a) # 可以返回函数 模板中可以调用
return render_template('index.html', name='lqz', age=19, user=user,add=add,a=a)
if __name__ == '__main__':
app.run()
html页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<div>{{name}}</div>
<div>{{age}}</div>
<h3>列表取值</h3>
<!--<p>{{列表[0]}}</p>-->
<hr>
<h3>字典取值</h3>
<p>{{user.name}}</p>
<p>{{user.get('age')}}</p>
<hr>
<h3>函数</h3>
<p>{{add(7,8)}}</p>
<h3>循环</h3>
<h4>逻辑判断</h4>
{% if name %}
<h1>Hello {{ name }}!</h1>
{% else %}
<h1>Hello World!</h1>
{% endif %}
<h3>xss攻击</h3>
<!--{{a|safe}}-->
{{a}}
<h3>模板的include</h3>
<h3>模板的extends</h3>
</body>
</html>
请求
Request–>http请求中得东西,都能从request中取出来
from flask import Flask, render_template, request, redirect
app = Flask(__name__)
@app.route('/index')
def index():
print(request.url)
"""
# 请求相关信息
# request.json.get() 获取json数据
# request.method 提交的方法
# request.args get请求提及的数据
# request.form post请求提交的数据
# request.values post和get提交的数据总和
# request.cookies 客户端所带的cookie
# request.headers 请求头 是一个字典
# request.path 不带域名,请求路径
# request.full_path 不带域名,带参数的请求路径
# request.script_root
# request.url 带域名带参数的请求路径
# request.base_url 带域名请求路径
# request.url_root 域名
# request.host_url 域名
# request.host 127.0.0.1:5000 服务器地址
# request.files 上传文件
# obj = request.files['the_file_name']
# obj.save('/var/www/uploads/' + secure_filename(f.filename))
"""
return request.url
if __name__ == '__main__':
app.run(debug=True)
响应
from flask import Flask, render_template, request, redirect,make_response
app = Flask(__name__)
def hello_world():
"""
return "字符串"
return render_template('html模板路径',**{})
return redirect('/index.html')
return jsonify({'k1':'v1'}) 也可以是一个列表
"""
# 向响应中写cookie
# response = make_response(render_template('index.html'))
# response是flask.wrappers.Response类型
# response.delete_cookie('key') # 删除cookie
# response.set_cookie('key', 'value') 设置返回的cookie
# response.headers['X-Something'] = 'A value'
# return response
return 'Hello World!'
if __name__ == '__main__':
app.run(debug=True)
cbv流程加装饰器
### cbv中加装饰器
1 使用步骤:在类中加入类属性:
def outer(func):
def inner(*args, **kwargs):
username = request.args.get('username')
password = request.args.get('password')
print(username, password)
if username == 'root' and password == '123':
res = func(*args, **kwargs)
return res
else:
return '账号或密码错误'
return inner
class ItemAPI(MethodView):
# 在这里加上装饰器之后 下面的所有方法都有
decorators = [装饰器,装饰器2] # 先写的装饰器放在最内部---》最后执行
def get(self):
# print(url_for('xxx'))
print(url_for('item'))
return 'get'
def post(self):
return 'post'
2 源码中
if cls.decorators:
for decorator in cls.decorators:
# 这就是装饰器的本质原理
view = decorator(view)
'''
@装饰器
def view()
'''
session的使用
# cookie 是客户端浏览器的键值对
# session是存在于服务端的键值对
# flask的session存在哪了?
加密后放到了cookie中
from flask import Flask, request, session
from flask.views import MethodView
app = Flask(__name__)
app.secret_key = 'asdfasdf'
@app.route('/login', methods=['GET'])
def login():
name = request.args.get('name')
# 假设登录成功
# 设置session进去
session['name'] = name
return 'hello'
@app.route('/', methods=['GET'])
def index():
print(session.get('name'))
# 可以直接取出session
res = session.get('name')
if res:
return '欢迎你,%s' % res
else:
return '您没有登录'
if __name__ == '__main__':
app.run()
session执行大概流程
# 1 登录成功---》放到session中数据----》把session中数据取出来,加密(dump)---》放到cookie-----》返回给前端--》save_session
# 2 请求来了---》请求中携带了cookie ---》取出cookie-->解密(load)得到数据--》把数据放到session中---》进入视图函数--》后续视图函数中直接使用session.get 就能取到当时放入的值--》open_session
# 不同浏览器,放的不一样,取出来也不一样
session 第三方使用
1 由于原生的flask中session是加密后放到了cookie中
2 我们想保存到文件中,数据库中,redis(比较多)。。。
3 借助于第三方:flask-session
1 第一种使用方式
from flask import Flask,session
import redis
from flask_session import RedisSessionInterface
app = Flask(__name__)
conn=redis.Redis(host='127.0.0.1',port=6379)
app.session_interface=RedisSessionInterface(conn,key_prefix='lqz') # app.secret_key='dafasdf' 不需要指定
@app.route('/set_session')
def set_session():
session['name']='lqz'
return 'session写入了,写了name=lqz'
@app.route('/get_session')
def get_session():
# s=session['name']
s=session.get('name','娶不到')
return '获取到的session是'+s
if __name__ == '__main__':
app.run()
2 第二种方式 通过配置文件设置
from flask_session import Session
# 方式一
app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_REDIS'] = Redis(host='127.0.0.1',port='6379')
app.config['SESSION_KEY_PREFIX']='lqz'
3 注意:设置session的过期时间,在配置文件中设置
app.config['PERMANENT_SESSION_LIFETIME']=timedelta(seconds=7)
flask的闪现
#1 它是:flash 翻译过来的
#2 闪现的作用
在某次请求中,有些数据,可以放在闪现中----》下次请求,从闪现中取出来使用
取一次就没了,下次再取就是空的
谁(浏览器)放的 ,谁(浏览器)才能取到
实际上放了session中了---》cookie
# 3 如何设置,如何取值
###基本使用
# 设置
from flask import Flask, url_for, render_template, request, flash, get_flashed_messages
from flask.views import MethodView
app = Flask(__name__)
app.debug = True
# 写一个类 继承 MethodView
### cbv中加装饰器
# 1
# 使用步骤:在类中加入类属性:
def outer(func):
def inner(*args, **kwargs):
username = request.args.get('username')
password = request.args.get('password')
print(username, password)
if username == 'root' and password == '123':
res = func(*args, **kwargs)
return res
else:
# 设置闪现
flash('用户名或密码错误,%s' % username)
return render_template('重定向的地址')
return inner
def login_required():
# 取出闪现
user = request.args.get('username')
# 取值(注意取出来的格式,列表套元组)
res = get_flashed_messages(True, category_filter=['login'])
return ('error %s' % res)
请求扩展
# 是几个装饰器--》功能是完成类似于django 的中间件--》在请求来和请求走的某些位置执行它
1 before_request:任意一次请求来了,都会执行这个装饰器装饰的函数 类似于django中间件的 process_request
2 after_request:任意一次请求走了,就会执行这个装饰器装饰的函数 process_response
#1 before_request
@app.before_request
def before_request():
# 1 判断如果没有登录,重定向到登录
if session.get("name") or 'login' in request.path:
print('请求来了1')
# 2 做频率限制
# 3 登录认证,认证通过,在request.user 当前登录用户 jwt认证
else:
return redirect('/login')
@app.before_request
def before_request():
print('请求来了2')
#2 after_request
@app.after_request
def after_request(response):
# 1 在响应头中加入一些数据 --》跨域处理
response.headers['ee'] = 'xx'
print('请求走了1')
return response
@app.after_request
def after_request(response):
print('请求走了2')
# 必须returnresponse
return response
"""
执行流程是从上往下执行 after_request回去是重下往上
比如:
请求来了
请求来了2
视图函数
请求走了2
请求走了1
"""
3 before_first_request # 新版本去掉了 第一次请求时,跟浏览器无关
4 teardown_request :每一个请求之后绑定一个函数,即使遇到了异常 打印信息
@app.teardown_request
def teardown_request(error):
print(error)
5 errorhandler:监听http响应码:只要响应码对应,就会执行对应的函数
路径不存在时404,服务器内部错误500
@app.errorhandler(404)
def error_404(error):
print('----',error)
return render_template('404.html')
6 template_global :标签
7 template_filter:过滤器
g对象的使用
from flask import Flask, g
# g 对象 global 全局的意思---》每次请求---》这个g一直存在--》可以设置值和取值
# g本质是为了避免request对象 放值导致的数据污染问题,以后都用g放入值和使用
app = Flask(__name__)
app.secret_key = 'asdfasdf'
@app.before_request
def before():
# jwt认证---》认证通过--》request.user=当前登录用户
# g.user=当前登录用户
g.name = 'lqz' # 放入了
@app.after_request
def after(response):
print('----', g.name)
return response
def showName():
print('showName', g.name)
@app.route('/', methods=['GET'])
def index():
# 取出g中得值
print(g.name)
showName()
return '欢迎你'
if __name__ == '__main__':
app.run()
蓝图
首先是init.py
from flask import Flask
# 这里是视图中的模板文件
app = Flask(__name__,template_folder='templates',static_folder='statics',static_url_path='/static')
# 需要把全部的app文件导入到init中注册
from .views.account import account
from .views.blog import blog
from .views.user import user
app.register_blueprint(account)
app.register_blueprint(blog)
app.register_blueprint(user)
======================================================
# views下的app文件中
from flask import Blueprint # 简称蓝图对象
from flask import render_template
from flask import request
# 蓝图对象(Blueprint)
account = Blueprint('account', __name__)
# 每个app中都可以生成一个蓝图对象
# 用起来,等同于app对象
@account.route('/login.html', methods=['GET', "POST"])
def login():
return render_template('login.html')
=================================================================
run.py中
# 把视图下的init.py中注册的app导入即可
from pro_flask import app
if __name__ == '__main__':
app.run()