flask
小猿取经:https://www.cnblogs.com/xiaoyuanqujing/protected/articles/11715484.html
flask与django的区别
1 django:是一个同步框架,orm,模板都是自己写的,如果要快速开发一个比较大的项目就用django,什么都有
2 flask:也是一个同步框架,orm不是自己写的,jinja2,flask小项目,可以做大项目,什么都没有,需要自己开发
3 tormado:异步框架,什么都没有
wsgiref
wsgiref模块就是python基于wsgi协议开发的服务模块
from wsgiref.simple_server import make_server
def mya(environ, start_response):
print(environ)
start_response('200 OK', [('Content-Type', 'text/html')])
if environ.get('PATH_INFO') == '/index':
data=b"jason is sb"
elif environ.get('PATH_INFO') == '/login':
data=b"tank is dsb"
else:
data = b'<h1>Hello, web!</h1>'
return [data]
if __name__ == '__main__':
myserver = make_server('', 8011, mya)
print('监听8011')
myserver.serve_forever()
werkzeug
Werkzeug是一个WSGI工具包,他可以作为一个Web框架的底层库。这里稍微说一下, werkzeug 不是一个web服务器,也不是一个
web框架,而是一个工具包,官方的介绍说是一个 WSGI 工具包,它可以作为一个 Web 框架的底层库,因为它封装好了很多 Web框架的东西,例如Request,Response
# pip install flask
from werkzeug.wrappers import Request,Response
@Request.application
def hello(request):
return Response("hello werkzeug")
if __name__ == '__main__':
from werkzeug.serving import run_simple
run_simple("127.0.0.1",5000,hello)
flask的快速使用
from flask import Flask
#实例化一个flask对象
app=Flask(__name__)
# 将“”和视图函数index的对应条件添加到路由中
@app.route("/")
def index():
return "hello flask"
if __name__ == '__main__':
'''
self是app app是Flask对象 对象加括号执行
对象加括号执行 执行的是app.__call__
'''
app.run()
flask四剑客
'''
直接返回字符串 相当于 django里的HttpResponse
render_template 相当于 django里的render 返回HTML页面 要创建一个templates文件夹,把所有的html文件都放在templates文件夹中
redirect 相当于 django里的redirect 跳转页面(个人认为理解为跳转路由更为准确)
jsonify 将可以序列化的数据转化为json
'''
from flask import Flask, render_template, redirect, jsonify
app = Flask(__name__)
# 返回字符串
@app.route("/")
def index():
return "ok"
# 返回html页面
@app.route("/index")
def index1():
return render_template("index.html")
# 跳转页面
@app.route("/login")
def index2():
return redirect("/")
# 返回json
@app.route("/json")
def json11():
data = {'name': "tank", 'love': "piao"}
return jsonify(data)
if __name__ == '__main__':
app.run()
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>你好啊,jsaon dsb</h1>>
</body>
</html>
flask的配置文件
from flask import Flask
app = Flask(__name__)
# 方式一:(app属性的方式):它只能配置两项,一个是debug 一个是secert_key
# app.debug=True
# 方式二 :(app.config字典的形式)
# app.config["DEBUG"]=True
# 方式三:(以一个py文件作为配置文件)文件所在位置
# app.config.from_pyfile("setting.py")
#方式四:(以类的形式,推荐使用)
app.config.from_object("settingobj.TestConfig")
@app.route("/")
def index():
return "ojbfddgfsfk"
if __name__ == '__main__':
app.run()
setting.py
DEBUG=True
settingobj.py
class Config:
DEBUG = False
class ProductConfig(Config):
pass
class TestConfig(Config):
DEBUG = True
路由本质以及有名分组
from flask import Flask, url_for
app = Flask(__name__)
# @app.route("/")
def index():
return "ok"
# @app.route("/")和下面的app.add_url_rule一样
# 如果写成下面的形式,就相当于django中的url文件
# add_url_rule参数的endpoint的作用:做反向解析,取别名用的
# add_url_rule参数的methodst的作用:访问方式,允许某些方式访问
# add_url_rule参数的strict_slashes的作用:对url最后的/符号是否严格方式
# add_url_rule参数的view_func的作用:视图函数名称
# add_url_rule参数的redirect_to的作用:重定向
app.add_url_rule("/", view_func=index, endpoint="index123", methods=["POST", "GET"])
def index1():
print(url_for("index123")) # 反向解析 找index123
return "123"
app.add_url_rule("/index1", view_func=index1, strict_slashes=False, redirect_to="/index2")
# 只有有名分组
def index2(yy):
print(yy)
return "12345"
app.add_url_rule("/index2/<int:yy>", view_func=index2)
if __name__ == '__main__':
app.run()
路由正则匹配
'''
写类 继承BaseConverter
注册 app.url_map.converters['regex']=RegexConverter
使用 @app.route('/index/<regex("d+"):nid>') 正则表达式会当做第二个参数传递到类中
'''
from flask import Flask,views,url_for
from werkzeug.routing import BaseConverter
app=Flask(import_name=__name__)
class RegexConverter(BaseConverter):
# 自定义url匹配正则表达式
def __init__(self,map,regex):
super(RegexConverter,self).__init__(map)
self.regex=regex
def to_python(self, value):#可以不写
# 路由匹配时,匹配成功后传递给视图函数中参数的值
print("to_python:",type(value),value)
return int(value)
def to_url(self, value):#可以不写
# 使用to_url反向生成url时,传递的参数经过该方法处理,返回的值用于生成url中的参数
print("to_url:",type(value),value)
val=super(RegexConverter,self).to_url(value)
return val+"123"
#添加到flask中
app.url_map.converters['regex']=RegexConverter
@app.route('/index/<regex("d+"):nid>')
def index(nid):
print("nid:",type(nid),nid)
print(url_for('index',nid='888'))
return "Index"
if __name__ == '__main__':
app.run()
'''
http://127.0.0.1:5000/index/123
to_python: <class 'str'> 123
nid: <class 'int'> 123
to_url: <class 'str'> 888
/index/888123
'''
cbv
from flask import Flask,views,url_for
app=Flask(__name__)
#原始写法:
#如果继承的是views.View必须实现 def dispatch_request(self):
class IndexView(views.View):
methods = ["POST","GET"]
# decorators = ['装饰器的函数对象']
def dispatch_request(self):
return "index"
# app.add_url_rule("/index",view_func=view)(View中as_view函数中嵌套的view)
app.add_url_rule("/index",view_func=IndexView.as_view(name="index"),endpoint="123")#name="index"相当于反向解析 若有endpoint 以endpoint为主
# 第二种写法
class LoginView(views.MethodView):
def post(self):
return "post"
def get(self):
print(url_for("123"))
return "get"
app.add_url_rule("/login",view_func=LoginView.as_view(name="login"))
if __name__ == '__main__':
app.run()
模板渲染
from flask import Flask,render_template,Markup
app=Flask(__name__)
def ff(arg,b):
return Markup(arg+b)#Markup相当于django中的make_safe
@app.route("/")
def index():
a = 123
list_info = {
1: {"name": "tank", "long": 160, "颜值": 50},
2: {"name": "jason", "long": 170, "颜值": 60},
3: {"name": "饼", "long": 190, "颜值": 80}
}
html ="<h1> jason is sb</h1>"
return render_template("index1.html",num=a,user_dic=list_info,htm=html,ff=ff)
if __name__ == '__main__':
app.run()
index1.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<body>
<h1>{{num}}</h1>
{% for k,v in user_dic.items() %}
<tr>
<td>{{k}}</td>
<td>{{v.name}}</td>
<td>{{v.long}}</td>
<td>{{v.get("颜值")}}</td>
</tr>
{% endfor %}
{% if num>1234 %}
<h1>hello {{num}}</h1>
{% else %}
<h1>tank is dsb</h1>
{% endif %}
{{htm|safe}}
{{ff(htm,"rrr")}}
</body>
</html>
请求与响应
from flask import Flask,request,render_template,redirect,jsonify,make_response
app=Flask(__name__)
@app.route("/")
def inde():
# 请求相关的
print("request.method",request.method)#提交的方法
print("request.args",request.args)#get请求提及的数据
print("request.form",request.form)#post请求提交的数据
print("request.values",request.values)#post和get提交的数据总和
# 响应相关
# response=make_response("ojbk")
response=make_response(render_template("index.html"))
response.set_cookie("name","egon is dsb")
response.delete_cookie("name")
response.headers["x-ssss"]="jason is sb"
return response
if __name__ == '__main__':
app.run()
session
from flask import Flask,session
app=Flask(__name__)
app.secret_key="jdjdjdj"
app.config['SESSION_COOKIE_NAME']="sdb"
'''
django的session
1 先产生一个随机的字符串 key
2 存key---》session对应,存到数据库
3 把它key传到前端 设置cookies
'''
'''
flask的session存的步骤
1 将session的这个字段做加密得到val
2 配置文件中SESSION_COOKIE_NAME作为key
3 设置cookies 以上述的key val做键值
flask的session取得步骤
1 获取cookie是中键为SESSION_COOKIE_NAME的值
2 将第一步获取的值作为解密操作得到真的val值
'''
@app.route("/")
def index():
session['name']="jason"
return "ok"
@app.route("/login")
def login():
print(session["name"])
return "ojbk"
if __name__ == '__main__':
app.run()
闪现
from flask import Flask,flash,get_flashed_messages
app=Flask(__name__)
app.secret_key="ssdd"
'''
闪现的特点:
1 没有设置 取得不会报错的 返回一个空列表
2 设置了就可以在任何一个视图函数中取
3 取了一次就没有了 但是在同一次请求中可以取多次
'''
@app.route("/")
def index1():
flash("jason 嘴硬")
return "333"
@app.route("/index")
def index():
flash("你错了")
flash("你就错了","老婆")#相当于value key
return "123"
@app.route("/login")
def login():
print(get_flashed_messages())#['jason 嘴硬', '你错了', '你就错了']
print(get_flashed_messages(with_categories=True))#[('message', 'jason 嘴硬'), ('message', '你错了'), ('老婆', '你就错了')]
print(get_flashed_messages(category_filter=("老婆")))#['你就错了']
return "ok"
if __name__ == '__main__':
app.run()